2017-07-02 51 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的详细信息。