webpack2代码拆分和CommonsChunkPlugin

时间:2017-07-04 14:35:42

标签: javascript requirejs webpack-2

我使用代码拆分和CommonsChunkPlugin遇到了问题。我已经习惯了require.js文件自动缓存的地方。我也使用libraryTarget: 'amd'进行网络配置。

考虑到这两个简单的文件,这是我得到的输出:

// fileA.js
import $ from 'jquery'

// fileB.js
import $ from 'jquery'

   Asset    Size  Chunks                    Chunk Names
fileB.js  271 kB       0  [emitted]  [big]  fileB
fileA.js  271 kB       1  [emitted]  [big]  fileA

因此,fileAfileB这两个文件都包含jquery。此外,我可以在html文件中使用这些文件。

require(['./dist/fileA.js', './dist/fileB.js'], function () {
})

根据文档,我可以使用CommonsChunkPlugin基本上将jquery提取到自己的文件中,所以我的配置如下所示:

new webpack.optimize.CommonsChunkPlugin({
  name: 'common'
}),

导致此输出:

    Asset       Size  Chunks                    Chunk Names
 fileB.js  635 bytes       0  [emitted]         fileB
 fileA.js  617 bytes       1  [emitted]         fileA
common.js     274 kB       2  [emitted]  [big]  common

但是现在我无法使用上述require块,因为common.js还包含了webpack运行时。我现在得到的只是Uncaught ReferenceError: webpackJsonp is not defined错误。

所以我需要的是:

  1. fileA.js(仅包含" fileA"代码,需要jquery)
  2. fileB.js(仅包含" fileB"代码,需要jquery)
  3. jquery.js(所有jquery的东西)
  4. common.js(仅包含webpack的运行时)
  5. 我已为fileAfileB尝试了类似的内容,但它的输出基本相同:

    define(['jquery'], function ($) {
    
    })
    

    只有在加载脚本(如fileA)并将其作为依赖项(与requirejs一样)时,才应加载(供应商)库。

    这可以实现吗?我多次浏览webpack2文档,但找不到任何可以帮助我的东西......

    编辑:好的,在一些github问题的帮助下,我设法通过以下配置获得正确的资产生成:

    module.exports = {
      entry: {
        jquery: ['jquery'],
        vue: ['vue'],
        fileA: ['./src/fileA.js'],
        fileB: ['./src/fileB.js'],
        fileC: ['./src/fileC.js']
      },
      output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist',
        filename: '[name].js',
        libraryTarget: 'amd'
      }
    }
    
    module.exports.plugins = (module.exports.plugins || []).concat([
      new webpack.optimize.CommonsChunkPlugin({
        name: ['vue', 'jquery']
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'common',
        chunks: ['vue', 'jquery'],
        minChunks: Infinity
      }),
      new webpack.optimize.OccurrenceOrderPlugin()
    ])
    

    我将源文件更改为:

    // fileA.js
    import $ from 'jquery'
    import Vue from 'vue'
    // fileB.js
    import $ from 'jquery'
    // fileC.js
    import Vue from 'vue'
    

    这是输出:

       vue.js     193 kB       0  [emitted]         vue
     fileC.js  447 bytes       1  [emitted]         fileC
     fileB.js  579 bytes       2  [emitted]         fileB
     fileA.js  666 bytes       3  [emitted]         fileA
    jquery.js     269 kB       4  [emitted]  [big]  jquery
    common.js    5.78 kB       5  [emitted]         common
    

    但是,在.html文件中使用它会导致以下错误:

    <body>
      <script src="./dist/common.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.3/require.js"></script>
      <script>
        require(['./dist/fileA.js', './dist/fileB.js', './dist/fileC.js'], function (a, b, c) {
        })
      </script>
    </body>
    

    fileAfileC ...

    都会发生以下错误
    common.js:55 Uncaught TypeError: Cannot read property 'call' of undefined
        at __webpack_require__ (common.js:55)
        at Object.7 (fileA.js:16)
        at __webpack_require__ (common.js:55)
        at Object.6 (fileA.js:6)
        at __webpack_require__ (common.js:55)
        at webpackJsonpCallback (common.js:26)
        at fileA.js:1
        at Object.execCb (require.js:1696)
        at Module.check (require.js:883)
        at Module.enable (require.js:1176)
    

    修改

    我创建了一个显示我遇到的问题的repo on github。根据Rafael De Leon的回答,我现在使用System.import('<module>')异步导入其他文件。 main.ts通过此语法导入fileA.ts,导致在需要output.js(已编译的main.ts文件)时出错。在使用fileA加载output.js时似乎发生了错误...我还创建了github issue,因为我认为这是一个错误。

1 个答案:

答案 0 :(得分:0)

  

只有在加载脚本(如fileA)并将其作为依赖项(与requirejs一样)时,才应加载(供应商)库。

如果你想要这个结果,CommonsChunkPlugin并不是你想要的。该插件用于将不同条目或其他CommonChunkPlugin使用的文件聚合到一个文件中。

我认为您正在寻找require.ensureval bCollected = b.groupBy('id).agg(collect_list('text).as("texts") val ab = a.join(bCollected, a("id") == bCollected("id"), "left") 来加载&#34;供应商&#34;按需提供文件

否则jq snippet from jqplay将起作用