2017-07-02 38 views
0

我在學習React,並希望瞭解如何爲項目配置網絡包。WebPack配置 - 什麼是正確的代碼,它是什麼意思

如果有人能告訴我下面的代碼行正在做什麼,那將會很棒。

const fs = require('fs') 
 
const path = require('path') 
 
const webpack = require('webpack') 
 

 
function isDirectory(dir) { 
 
    return fs.lstatSync(dir).isDirectory() 
 
} 
 

 
const SubjectsDir = path.join(__dirname, 'subjects') 
 
const SubjectDirs = fs.readdirSync(SubjectsDir).filter(function (dir) { 
 
    return isDirectory(path.join(SubjectsDir, dir)) 
 
}) 
 

 
module.exports = { 
 
    devtool: 'source-map', 
 

 
    entry: SubjectDirs.reduce(function (entries, dir) { 
 
    if (fs.existsSync(path.join(SubjectsDir, dir, 'exercise.js'))) 
 
     entries[dir + '-exercise'] = path.join(SubjectsDir, dir, 'exercise.js') 
 

 
    if (fs.existsSync(path.join(SubjectsDir, dir, 'solution.js'))) 
 
     entries[dir + '-solution'] = path.join(SubjectsDir, dir, 'solution.js') 
 

 
    if (fs.existsSync(path.join(SubjectsDir, dir, 'lecture.js'))) 
 
     entries[dir + '-lecture'] = path.join(SubjectsDir, dir, 'lecture.js') 
 

 
    return entries 
 
    }, { 
 
    shared: [ 'react', 'react-dom' ] 
 
    }), 
 

 
    output: { 
 
    path: '__build__', 
 
    filename: '[name].js', 
 
    chunkFilename: '[id].chunk.js', 
 
    publicPath: '__build__' 
 
    }, 
 

 
    resolve: { 
 
    extensions: [ '', '.js', '.css' ] 
 
    }, 
 

 
    module: { 
 
    loaders: [ 
 
     { test: /\.css$/, loader: 'style!css' }, 
 
     { test: /\.js$/, exclude: /node_modules|mocha-browser\.js/, loader: 'babel' }, 
 
     { test: /\.woff(2)?$/, loader: 'url?limit=10000&mimetype=application/font-woff' }, 
 
     { test: /\.ttf$/, loader: 'file' }, 
 
     { test: /\.eot$/, loader: 'file' }, 
 
     { test: /\.svg$/, loader: 'file' }, 
 
     { test: require.resolve('jquery'), loader: 'expose?jQuery' } 
 
    ] 
 
    }, 
 

 
    plugins: [ 
 
    new webpack.optimize.CommonsChunkPlugin({ name: 'shared' }) 
 
    ], 
 

 
    devServer: { 
 
    quiet: false, 
 
    noInfo: false, 
 
    historyApiFallback: { 
 
     rewrites: [ 
 
     { from: /ReduxDataFlow\/exercise.html/, 
 
      to: 'ReduxDataFlow\/exercise.html' 
 
     } 
 
     ] 
 
    }, 
 
    stats: { 
 
     // Config for minimal console.log mess. 
 
     assets: true, 
 
     colors: true, 
 
     version: true, 
 
     hash: true, 
 
     timings: true, 
 
     chunks: false, 
 
     chunkModules: false 
 
    } 
 
    } 
 
}

這個情報是從培訓課程來了,但他們沒有解釋什麼線都在做。

+1

如果您還不熟悉webpack,請從以下優秀資源開始:https://webpack.js.org/concepts/然後轉到此https://webpack.js.org/configuration/ –

+0

哪些行需要有待解釋? – webdeb

+0

抱歉不具體。想了解module.exports內部是什麼。 –

回答

2

Webpack是我們稱之爲JavaScript應用程序的模塊打包程序。你可以用它做一些事情,幫助客戶端瀏覽器下載並運行你的代碼。對於React,它有助於將JSX代碼轉換爲純JS,以便瀏覽器可以理解它。 JSX本身不會在瀏覽器中運行。我們甚至可以使用插件來幫助縮小代碼,注入HTML,將各種代碼組捆綁在一起等等。現在我們來介紹一下Webpack的介紹,讓我們來看看代碼。我將從最高層開始。如果您只對Webpack配置對象感興趣,請隨意跳至#3

  1. 以下代碼將需要此文件中所需的模塊。 fs是「文件系統」的簡稱,是一個爲您提供可以訪問項目文件系統的功能的模塊。 path是一個常用模塊,用於解析或創建文件的路徑名,並且非常易於使用!然後我們有webpack模塊,通過它我們可以訪問webpack特定的功能(即:像webpack.optimize.UglifyJsPlugin這樣的webpack插件)。

    const fs = require('fs') 
    const path = require('path') 
    const webpack = require('webpack') 
    
  2. 首先建立一個輔助函數來確定是否不是在文件系統中,這些接下來的幾行讀取是一個目錄。

    function isDirectory(dir) { 
        return fs.lstatSync(dir).isDirectory() 
    } 
    
    const SubjectsDir = path.join(__dirname, 'subjects') 
    const SubjectDirs = fs.readdirSync(SubjectsDir).filter(function (dir) { 
        return isDirectory(path.join(SubjectsDir, dir)) 
    }) 
    
  3. devtool指定你想要的開發工具來使用,以幫助調試。選項在這裏列出:https://webpack.github.io/docs/configuration.html#devtool。這對於幫助您確切確定哪些文件,行和列錯誤來自哪裏非常有用。

    devtool: 'source-map' 
    
  4. 接下來的幾行告訴Webpack從哪裏開始打包文件。這些初始文件被稱爲entry points。 Webpack配置對象中的entry屬性應該是一個對象,其鍵用於確定捆綁軟件的名稱,值指向條目文件的相對路徑或node_module的名稱。您還可以將一組文件傳遞給每個入口點。這將使這些文件中的每一個按照該密鑰指定的名稱被捆綁到一個文件中 - 即:reactreact-dom將分別被解析並將其輸出捆綁在名稱shared下。

    entry: SubjectDirs.reduce(function (entries, dir) { 
        if (fs.existsSync(path.join(SubjectsDir, dir, 'exercise.js'))) 
        entries[dir + '-exercise'] = path.join(SubjectsDir, dir, 'exercise.js') 
    
        if (fs.existsSync(path.join(SubjectsDir, dir, 'solution.js'))) 
        entries[dir + '-solution'] = path.join(SubjectsDir, dir, 'solution.js') 
    
        if (fs.existsSync(path.join(SubjectsDir, dir, 'lecture.js'))) 
        entries[dir + '-lecture'] = path.join(SubjectsDir, dir, 'lecture.js') 
    
        return entries 
    }, { 
        shared: [ 'react', 'react-dom' ] 
    }), 
    

    在減少功能,我們只需通過SubjectsDir讀,確定文件exercise.jslecture.js & solution.js是否存在,然後提供的路徑,這些文件是由dir + '-' + filename(即確定的主要名字關聯的值:myDir-exercise )。這可能最終會看起來像下面如果只exercise.js存在:

    entry : { 
        'myDir-exercise': 'subjectDir/myDir/exercise.js', 
        share: ['react', 'react-dom'] 
    } 
    
  5. 後,我們提供入口點的WebPack配置對象,我們必須指定我們想要的WebPack輸出捆綁這些文件的結果。這可以在output屬性中指定。

    output: { 
        path: '__build__', 
        filename: '[name].js', 
        chunkFilename: '[id].chunk.js', 
        publicPath: '__build__' 
    }, 
    

    path屬性定義了輸出目錄的絕對路徑。在這種情況下,我們稱之爲__build__

    filename屬性定義每個入口點文件的輸出名稱。 Webpack明白,通過指定'[name]',您指的是您分配給entry屬性中每個入口點的密鑰(即:sharedmyDir-exercise)。

    chunkFilename屬性與filename屬性類似,但對於可由CommonChunksPlugin(請參見下文)指定的非條目塊文件。使用[id]類似於使用[name]

    publicPath屬性定義了您的文件所在的公共URL,例如通過瀏覽器訪問您的文件的URL。

  6. resolve屬性告訴Webpack如何解決你的文件,如果它由於某種原因找不到它們。我們可以通過extensions作爲其中的一個屬性。 extensions屬性告訴Webpack如果在代碼中沒有指定文件擴展名,那麼該文件將在文件上嘗試。

    resolve: { 
        extensions: [ '', '.js', '.css' ] 
    }, 
    

    例如,假設我們有下面的代碼

    const exercise = require('./exercise'); 
    

    我們可以離開了.js,因爲我們已經提供了字符串中的WebPack配置的resolve財產的WebPack會嘗試和追加.js在捆綁時間查找您的文件。從Webpack 2開始,我們不再需要指定一個空字符串作爲resolve屬性的第一個元素。

  7. module屬性告訴Webpack如何處理我們項目中的模塊。我們可以在這裏添加幾個屬性,我建議看看文檔以獲取更多詳細信息。 loaders是一個常用的屬性,我們可以告訴Webpack如何解析我們項目中的特定文件類型。每個加載器中的test屬性只是一個正則表達式,它告訴Webpack運行此加載器的文件。例如,此/\.js$/將對以.js結尾的文件運行指定的加載程序。 babel-loader是一個廣泛使用的JavaScript + ES6加載器。 exclude屬性告訴Webpack哪些文件不與指定的加載器一起運行。 loader屬性是加載器的名稱。從Webpack 2開始,我們不再能夠從字符串中刪除-loader,正如我們在這裏看到的。

  8. 插件具有廣泛的功能。如前所述,我們可以使用插件來幫助縮小代碼或構建在整個應用程序中使用的塊,如reactreact-dom。在這裏我們看到正在使用CommonChunksPlugin,它會將條目名稱shared下的文件合併爲一個塊,以便它們可以與應用程序的其餘部分分離。

  9. 最後,我們有devServer屬性,該屬性指定webpack-dev-server行爲的某些配置,它是與webpack不同的模塊。此模塊對開發很有用,因爲您可以選擇不構建自己的Web服務器,並允許webpack-dev-server爲您的靜態文件提供服務。它也不會將輸出寫入您的文件系統,並且從Webpack配置對象的output屬性中的publicPath屬性(請參閱#5)指定的路徑從內存中的位置提供包。這有助於加快開發速度。要使用它,您只需運行webpack-dev-server而不是webpack。在線查看文檔以獲取更多詳細信息。

我們看過的配置對象遵循Webpack 1標準。在配置語法方面,Webpack 1和2之間有很多變化,這對於我們來說很重要。然而,這些概念仍然相同。查看文檔以獲取有關遷移到Webpack 2的信息以及更多Webpack 2的詳細信息。