webpack打包中的chunkhask的值会改变

我在项目中使用webpack时遇到了这样的问题:

webpack.config.js使用了两个entry,一个app是源代码,一个vendor是依赖包。output
的文件名使用chunkhash作为后缀,每一次执行npm run build生成的两个js文件,
当app中源代码改变了,再重新build,这时生成的两个js文件chunkhash值都会改变。

这是什么原因呢?webpack.config.js如下:

entry: {
    app: "./src/index",
    vendor: ["antd",'react','echarts','codemirror','echarts-for-react','react-dnd',
        'react-dnd-html5-backend','react-dom','react-fetch','react-redux','react-router',
        'superagent','react-router-redux','redux','redux-react-fetch','redux-thunk',
        'react-syntax-highlighter','g2','history','isomorphic-fetch','js-cookie',
        'lodash','moment','pubsub-js',"react-codemirror"]
}

output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle-[name]-[chunkhash].js',
    publicPath: '/'
},

<img>npm run build 结果截图</img>

阅读 3.7k
2 个回答

最近在整理一篇webpack文章。

的确,因为 vendor 包含着 webpack 启动时所需要的代码,而这里头代码会涉及到依赖解析中的模块ID(以依赖收集顺序递增的一个正整数)分配。然而 entry 有内容变更时,由于webpack的依赖收集规则会导致对应的 chunk 编号发生变动,其最后 runtime 也跟着变,而 runtime 又包含在 vendor 文件内,最后 verdor 也跟着变了,但实际上压根就没有改动过。

因此,核心的问题,分两步走:

1、生成稳定的模块ID

正整数递增的规则很明显太不靠谱了,好在 webpack2 以后内置了一个叫 named-modules-plugin 的模块,可以很轻松解决这个问题:

{
    plugins: [
        new webpack.NamedModulesPlugin()
    ]
}

2、分离runtime

前面我说模块的变动会导致 runtime 的变更,而 runtime 又包括在 vendor 里头,实际问题依然未解决。因此,需要把它从 vendor 中分离。

{
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
            names: [ 'vendor', 'manifest' ]
        })
    ]
}

新增一个 manifest 的 chunk,无须配合相应入口,目的只是为了分离 runtime,但必须放在数组的最后一个(按webpack规则,实际是第一个执行)。最后,你会发现多生成一个 manifest.js 文件,文件内容只是模块ID相关的东西,非常少。

这样才算构建一个真正可靠的 vendor。

manifest.js 文件非常小,但依然需要在页面中引用js,不过如果你介意可以利用 inline-manifest-webpack-plugin 把它放到 index.html 当中,可减少一次请求。

Happy coding!

happy coding!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进