mini-css-extractfrom-plugin将多个css chunk合并成一个css文件出问题

彻底解决 webpack 打包文件体积过大 - 简书
彻底解决 webpack 打包文件体积过大
webpack 把我们所有的文件都打包成一个 JS 文件,这样即使你是小项目,打包后的文件也会非常大。下面就来讲下如何从多个方面进行优化。
去除不必要的插件
刚开始用 webpack 的时候,开发环境和生产环境用的是同一个 webpack 配置文件,导致生产环境打包的 JS 文件包含了一大堆没必要的插件,比如 HotModuleReplacementPlugin, NoErrorsPlugin... 这时候不管用什么优化方式,都没多大效果。所以,如果你打包后的文件非常大的话,先检查下是不是包含了这些插件。
提取第三方库
像 react 这个库的核心代码就有 627 KB,这样和我们的源代码放在一起打包,体积肯定会很大。所以可以在 webpack 中设置
bundle: 'app'
vendor: ['react']
plugins: {
new webpack.optimize.CommonsChunkPlugin('vendor',
'vendor.js')
这样打包之后就会多出一个 vendor.js 文件,之后在引入我们自己的代码之前,都要先引入这个文件。比如在 index.html 中
&script src="/build/vendor.js"&&/script&
&script src="/build/bundle.js"&&/script&
除了这种方式之外,还可以通过引用外部文件的方式引入第三方库,比如像下面的配置
externals: {
'react': 'React'
externals 对象的 key 是给 require 时用的,比如 require('react'),对象的 value 表示的是如何在 global 中访问到该对象,这里是 window.React。这时候 index.html 就变成下面这样
&script src="//cdn.bootcss.com/react/0.14.7/react.min.js"&&/script&
&script src="/build/bundle.js"&&/script&
当然,个人更推荐第一种方式。
目前推荐用
的方式提取第三方库。
webpack 自带了一个压缩插件 ,只需要在配置文件中引入即可。
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
加入了这个插件之后,编译的速度会明显变慢,所以一般只在生产环境启用。
另外,服务器端还可以开启 gzip 压缩,优化的效果更明显。
什么是代码分割呢?我们知道,一般加载一个网页都会把全部的 js 代码都加载下来。但是对于 web app 来说,我们更想要的是只加载当前 UI 的代码,没有点击的部分不加载。
看起来好像挺麻烦,但是通过 webpack 的
就可以方便实现。具体的例子可以看下 react router 的官方示例 。不过这里还是讲下之前配置踩过的坑。
code split 是 ES6 的模块系统的,所以在导入和导出的时候千万要注意,特别是导出。如果你导出组件的时候用 ES6 的方式,这时候不管导入是用 CommomJs 还是 AMD,都会失败,而且还不会报错!
当然会踩到这个坑也是因为我刚刚才用 NodeJS,而且一入门就是用 ES6 的风格。除了这个之外,还有一点也要注意,在生产环境的 webpack 配置文件中,要加上 publicPath
path: xxx,
publicPath: yyy,
filename: 'bundle.js'
不然的话,webpack 在加载 chunk 的时候,路径会出错。
开始这个小节之前,可以先看下大神的一篇文章:。
对于静态文件,第一次获取之后,文件内容没改变的话,浏览器直接读取缓存文件即可。那如果缓存设置过长,文件要更新怎么办呢?嗯,以文件内容的 MD5 作为文件名就是一个不错的解决方案。来看下用 webpack 应该怎样实现
path: xxx,
publicPath: yyy,
filename: '[name]-[chunkhash:6].js'
打包后的文件名加入了 hash 值
const bundler = webpack(config)
bundler.run((err, stats) =& {
let assets = stats.toJson().assets
for (let i = 0; i & assets. i++) {
if (assets[i].name.startsWith('main')) {
name = assets[i].name
fs.stat(config.buildTemplatePath, (err, stats) =& {
if (err) {
fs.mkdirSync(config.buildTemplatePath)
writeTemplate(name)
手动调用 webpack 的 API,获取打包后的文件名,通过 writeTemplate 更新 html 代码。完整代码猛戳 。
这样子,我们就可以把文件的缓存设置得很长,而不用担心更新问题。
webpack 把我们所有的文件都打包成一个JS文件,这样即使你是一个小项目,打包后的文件也会非常大。下面就来讲下如何从多个方面进行优化。 去除不必要的插件 刚开始用 webpack 的时候,开发环境合生产环境用的是同一个 webpack 配置文件,导致生产环境打包的 JS...
无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到这篇好的文章:http://www.jianshu.com/p/42e11515c10f 写在前面的话阅读本文之前,先看下面这个webpack的配置文件,如果每...
最近在学习 Webpack,网上大多数入门教程都是基于 Webpack 1.x 版本的,我学习 Webpack 的时候是看了 zhangwang 的 &&入门 Webpack,看这篇就够了&& 写的非常好,不过是基于 Webpack 1.x 版本的,语法上和 Webpack...
写在开头 先说说为什么要写这篇文章, 最初的原因是组里的小朋友们看了webpack文档后, 表情都是这样的: (摘自webpack一篇文档的评论区) 和这样的: 是的, 即使是外国佬也在吐槽这文档不是人能看的. 回想起当年自己啃webpack文档的血与泪的往事, 觉得有必要...
从V1迁移到V2由于使用的是webpack版本是2.2.1,所以针对原文做了一些修改。针对webpack2的修改部分和添加的部分在最底部,文中已经改过来了。 写在前面的话阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限...
你说事情的轮廓清晰明了的出现在你脑海,但你的行动却偏离的轨迹。 你无奈拿出一根让你有些许恶心的香烟开始吞云吐雾。 你那慵懒的态度很难构建起理想与现实的桥梁。
我就是喜欢冬季的草,冬季的树。因为这才是最真的草,最真的木。 冬天的草,黄了,枯了,但却是最真实的。我们常说,人只有在临死的时候,才会表现出最真实的自己。因为再也不用顾虑,不用去想明天的生活和那些没完没了、繁琐、让你心烦意乱的小事。你的心情是舒畅的,吐的每一口气,说的每一句...
01 前几天,我的一位同事因为着凉肚子不舒服,夜里准备去趟医院。结果,她老公还把那款宇宙皆知的游戏打完一局,才送她去的医院。 她告诉我们这件事时,办公室里就有两种完全不同的声音,姑娘们都觉得这样的老公不关心妻子,小伙子们却觉得这样的老公超级靠谱不坑队友。 我在心里暗叹,果然...
Android系统应用框架篇:Activity启动流程(三) 关于作者 郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的Github提issue或者发邮件至与我交流。 关于文章...Webpack 常见静态资源处理 - 模块加载器(Loaders)+ExtractTextPlugin插件
webpack系列目录
基于webpack搭建纯静态页面型前端工程解决方案模板, 最终形态源码见github:
Webpack将所有静态资源都认为是模块,比如JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等等,从而可以对其进行统一管理。为此Webpack引入了加载器的概念,除了纯JavaScript之外,每一种资源都可以通过对应的加载器处理成模块。和大多数包管理器不一样的是,Webpack的加载器之间可以进行串联,一个加载器的输出可以成为另一个加载器的输入。比如LESS文件先通过less-load处理成css,然后再通过css-loader加载成css模块,最后由style-loader加载器对其做最后的处理,从而运行时可以通过style标签将其应用到最终的浏览器环境。
一 常用loader
安装css/sass/less loader加载器
cnpm install file-loader css-loader style-loader sass-loader ejs-loader html-loader jsx-loader image-webpack-loader --save-dev
webpack.config.js配置:
loaders: [
test: /\.((woff2?|svg)(\?v=[0-9]\.[0-9]\.[0-9]))|(woff2?|svg|jpe?g|png|gif|ico)$/,
loaders: [
// 小于10KB的图片会自动转成dataUrl
'url?limit=10240&name=img/[hash:8].[name].[ext]',
'image?{bypassOnDebug:true, progressive:true,optimizationLevel:3,pngquant:{quality:&65-80&,speed:4}}'
test: /\.((ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9]))|(ttf|eot)$/,
loader: 'url?limit=10000&name=fonts/[hash:8].[name].[ext]'
{test: /\.(tpl|ejs)$/, loader: 'ejs'},
{test: /\.css$/, loader: 'style-loader!css-loader'},
{ test: /\.scss$/, loader: 'style!css!sass'}
index.html 新增两个div
&div class=&small-webpack&&&/div&
&div class=&webpack&&&/div&
index.css 增加两个图片,同时将webpack.png(53kb) 和 small-webpack.png(9.8k)
.webpack {
background: url(../img/webpack.png) no-
height:500
.small-webpack {
background: url(../img/small-webpack.png) no-
height:250
index.js 引入css
require('../css/index.css');
执行webpack指令
查看生成的目录结构
其中并没有css文件,css被写入到了index.js中,index.js 部分截图
图片采用了url-loader加载,如果小于10kb,图片则被转化成 base64 格式的 dataUrl
css文件被打包进了js文件中
css被打包进了js文件,如果接受不了,可以强制把css从js文件中独立出来。官方文档是以插件形式实现:,
二:extract-text-webpack-plugin 插件介绍
Extract text from bundle into a file.从bundle中提取出特定的text到一个文件中。使用 extract-text-webpack-plugin就可以把css从js中独立抽离出来
$ npm install extract-text-webpack-plugin --save-dev
使用(css为例)
var ExtractTextPlugin = require(&extract-text-webpack-plugin&);
module.exports = {
loaders: [
{ test: /\.css$/, loader: ExtractTextPlugin.extract(&style-loader&, &css-loader&) }
plugins: [
new ExtractTextPlugin(&styles.css&)
它将从每一个用到了require(&*.css&)的entry chunks文件中抽离出css到单独的output文件
new ExtractTextPlugin([id: string], filename: string, [options])
id Unique ident for this plugin instance. (For advanded usage only, by default automatic generated)
filename the filename of the result file. May contain [name], [id] and [contenthash].
[name] the name of the chunk
[id] the number of the chunk
[contenthash] a hash of the content of the extracted file
allChunks extract from all additional chunks too (by default it extracts only from the initial chunk(s))
disable disables the plugin
ExtractTextPlugin.extract([notExtractLoader], loader, [options])
根据已有的loader,创建一个提取器(loader的再封装)
notExtractLoader (可选)当css没有被抽离时,加载器不应该使用(例如:当allChunks:false时,在一个additional 的chunk中)
loader 数组,用来转换css资源的加载器s
publicPath 重写该加载器(loader)的 publicPath 的设置
多入口文件的extract的使用示例:
let ExtractTextPlugin = require('extract-text-webpack-plugin');
// multiple extract instances
let extractCSS = new ExtractTextPlugin('stylesheets/[name].css');
let extractLESS = new ExtractTextPlugin('stylesheets/[name].less');
module.exports = {
loaders: [
{test: /\.scss$/i, loader: extractCSS.extract(['css','sass'])},
{test: /\.less$/i, loader: extractLESS.extract(['css','less'])},
plugins: [
extractCSS,
extractLESS
三:改造项目-抽离css
安装插件到项目
npm install extract-text-webpack-plugin --save-dev
配置webpack.config.js,加入ExtractTextPlugin和相关处理:
var webpack = require(&webpack&);
var path = require(&path&);
var srcDir = path.resolve(process.cwd(), 'src');
var nodeModPath = path.resolve(__dirname, './node_modules');
var pathMap = require('./src/pathmap.json');
var glob = require('glob')
var CommonsChunkPlugin = webpack.optimize.CommonsChunkP
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var entries = function () {
var jsDir = path.resolve(srcDir, 'js')
var entryFiles = glob.sync(jsDir + '/*.{js,jsx}')
var map = {};
for (var i = 0; i & entryFiles. i++) {
var filePath = entryFiles[i];
var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));
map[filename] = fileP
var html_plugins = function () {
var entryHtml = glob.sync(srcDir + '/*.html')
var r = []
var entriesFiles = entries()
for (var i = 0; i & entryHtml. i++) {
var filePath = entryHtml[i];
var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));
var conf = {
template: 'html!' + filePath,
filename: filename + '.html'
//如果和入口js文件同名
if (filename in entriesFiles) {
conf.inject = 'body'
conf.chunks = ['vendor', filename]
//跨页面引用,如pageA,pageB 共同引用了common-a-b.js,那么可以在这单独处理
//if(pageA|pageB.test(filename)) conf.chunks.splice(1,0,'common-a-b')
r.push(new HtmlWebpackPlugin(conf))
var plugins = [];
var extractCSS = new ExtractTextPlugin('css/[name].css?[contenthash]')
var cssLoader = extractCSS.extract(['css'])
var sassLoader = extractCSS.extract(['css', 'sass'])
plugins.push(extractCSS);
plugins.push(new CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity
module.exports = {
entry: Object.assign(entries(), {
// 用到什么公共lib(例如jquery.js),就把它加进vendor去,目的是将公用库单独提取打包
'vendor': ['jquery', 'avalon']
path: path.join(__dirname, &dist&),
filename: &[name].js&,
chunkFilename: '[chunkhash:8].chunk.js',
publicPath: &/&
loaders: [
test: /\.((woff2?|svg)(\?v=[0-9]\.[0-9]\.[0-9]))|(woff2?|svg|jpe?g|png|gif|ico)$/,
loaders: [
//小于10KB的图片会自动转成dataUrl,
'url?limit=10000&name=img/[hash:8].[name].[ext]',
'image?{bypassOnDebug:true, progressive:true,optimizationLevel:3,pngquant:{quality:&65-80&,speed:4}}'
test: /\.((ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9]))|(ttf|eot)$/,
loader: 'url?limit=10000&name=fonts/[hash:8].[name].[ext]'
{test: /\.(tpl|ejs)$/, loader: 'ejs'},
{test: /\.css$/, loader: cssLoader},
{test: /\.scss$/, loader: sassLoader}
resolve: {
extensions: ['', '.js', '.css', '.scss', '.tpl', '.png', '.jpg'],
root: [srcDir, nodeModPath],
alias: pathMap,
publicPath: '/'
plugins: plugins.concat(html_plugins())
其中,用ExtractTextPlugin 来抽离css
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCSS = new ExtractTextPlugin('css/[name].css?[contenthash]')
var cssLoader = extractCSS.extract(['css'])
var sassLoader = extractCSS.extract(['css', 'sass'])
plugins.push(extractCSS);
//conf - module - loaders
{test: /\.css$/, loader: cssLoader},
{test: /\.scss$/, loader: sassLoader}
注意事项:
css中img的路径会出现问题,通过设置publicPath 解决,采用绝对路径
publicPath: &/&
css单独抽离,打包成单独的css文件
html自动引用css文件
小于10k的图片,转成base64 格式的 dataUrl
webpack.png 会被压缩,减少文件大小
运行webpack后的项目的目录结构:
生成的 dist/index.html 自动引用了 index.css 和相关的js,由于设置了publicPath 所以相应的链接都采用了绝对路径
生成的 dist/index.css 小图片被转成了data:image形式:
css单独打包到css目录
html自动注入了link 标签
small-webpack.png 小于10k,被打包进了index.css
webpack.png 由原来的50+k 被压缩成 10- k
最后,运行 webpack-dev-server 看一下运行结果:
Webpack将所有静态资源都认为是模块,而通过loader,几乎可以处理所有的静态资源,图片、css、sass之类的。并且通过一些插件如extract-text-webpack-plugin,可以将共用的css抽离出来
下篇介绍改进webpack.config.js:
区分开发环境和生产环境
集成 gulp 实现自动构建打包部署
github 发布 前端自动化构建的项目模板
阅读(...) 评论()6.9k 次阅读
如果利用 webpack 将项目中的所有代码打包在一起,很多时候是不适用的,因为代码中有些东西我们总是希望将其拆分出来。比如:
样式表,希望利用 link 标签引入
使用概率较低的模块,希望后期需要的时候异步加载
框架代码,希望能利用浏览器缓存下部分不易变动的代码
下面是我在阅读 webpack 的官方文档时候,记录的一些笔记,部分地方使用了自己的话来讲,力图让它显得更易懂。
按需加载拆分
webpack 可以帮助我们将代码分成不同的逻辑块,在需要的时候加载这些代码。
使用 require.ensure() 来拆分代码
require.ensure()
是一种使用 CommonJS 的形式来异步加载模块的策略。在代码中通过 require.ensure([&fileurl&]) 引用模块,其使用方法如下:
require.ensure(dependencies: String[], callback: function(require), chunkName: String)
第一个参数指定依赖的模块,第二个参数是一个函数,在这个函数里面你可以使用 require 来加载其他的模块,webpack 会收集 ensure 中的依赖,将其打包在一个单独的文件中,在后续用到的时候使用 jsonp 异步地加载进去。
require.ensure(['./a'], function(require){
let b = require('./b');
let a = require('./a');
console.log(a+b)
以上代码,a
和 b 会被打包在一起,在代码中执行到这段代码的时候,会异步地去加载,加载完成后执行函数里面的逻辑。
let a = require('./a');
require.ensure(['./a'], function(require){
let b = require('./b');
console.log(a+b)
如果这样写,那么 a 不会和 b 打包在一起,因为 a 已经被打包在主代码中了。
require.ensure(['./c'], function(require){
let a = require('./a');
console.log(a)
require.ensure(['./c'], function(require){
let b = require('./b');
console.log(b)
以上代码中两个模块都依赖了 c 模块,这个时候会拆分出两个模块,其中都包含了 c 模块,因为在实际运用中,以上两个 require.ensure 的执行顺序不确定,执行与否也不确定,因此需要将 c 模块都打包进去。
require.ensure 还可以传入第三个参数,这个参数用来指定打包的包名,对于上面这种情况,c 模块被打包入了两个包中,如果事先明确这两个包都会被使用,那么不妨将这两个包合并为一个,这样就不会有 c 模块被打包两次的问题了,所以可以将 chunkName 指定为同一个名字。
require.ensure(['./c'], function(require){
let a = require('./a');
console.log(a)
require.ensure(['./c'], function(require){
let b = require('./b');
console.log(b)
ok,这样以上两个 require.ensure 拆出来的包就合并为同一个了。
开发者,可能希望能将工程中的所有引入的 CSS 拆分为单个文件,这样可以利用缓存,且利用 CSS 和 JavaScript 并行加载,来加速 web 应用。
使用 css-loader
为了加载 css,这里需要用到 css-loader,配置方法如下:
loaders: [{
test: /\.css$/,
exclude: /node_modules/,
loader: 'css-loader'
这样在代码中就可以写如下代码:
let css = require('./main.css');
console.log('' + css);
通过 require 一个 css 得到其内容,当然了这里 require('./main.css') 实际得到的是一个对象,需要调用其 toString 方法将其转换为字符串。在代码中引用一段 css,这常常不是我们想要的。为此可以使用 style-loader 在代码执行起来的时候,会将这些 css 插入到 style 标签中,只是这里 css 还是存在于 js 中的,是后来动态插入到页面中的:
loaders: [{
test: /\.css$/,
exclude: /node_modules/,
loader: 'style-loader!css-loader'
更多时候,是希望将 css 拆分为单个文件,然后使用 link 标签嵌入到 html 中,CSS 和 JavaScript 可以并行加载,css 还可以被缓存下来。
使用 extract-text-webpack-plugin 来拆分 css
为了使用这个插件首先需要通过 npm 来安装它:
npm i --save-dev extract-text-webpack-plugin
然后在 webpack 的配置文件中使用该插件:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = function () {
entry: './index.js',
path: './build',
filename: 'bundle.js'
loaders: [{
test: /\.css$/,
exclude: /node_modules/,
// 在 loader 中使用该插件
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
plugins: [
// 将其添加在插件中
new ExtractTextPlugin({ filename: 'bundle.css', disable: false, allChunks: true })
需要注意的是,对于 webpack1 和 webpack2 这个插件的配置方法是不同的,差别比较细微,详情请看官方文档
拆分业务代码与框架代码
通常一个 web 应用都会引用若干第三方库,这些第三方库通常比较稳定不会经常变动,但是如果将业务代码和框架代码打包在了一起,这样业务代码每次变动打包得到的结果都会变动,及时只改变了一个字符,浏览器也无法利用缓存,必须全部重新加载。因此,何不将第三方库单独打包在一起呢?
这里举个案例,一个 react 项目中使用了 react 和 react-dom 这两个包,我希望将他们打包在一起,将业务代码打包在一起。
下面一步一步来:
1. 安装 react 和 react-dom:
npm i react react-dom --save
2. 配置 entry,output 和 loader
先使用单入口,让代码工作起来。另外因为使用了 react 所以要使用 babel-loader 来加载 js
// webpack.config.js
module.exports = {
entry: 'index.js',
path: 'build/',
filname: '[name]@[chunkhash].js'
loaders:[{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel'
3. 编写业务代码
import React from 'react';
import ReactDOM from 'react-dom';
var Hello = React.createClass({
render: function() {
return &div&Hello {this.props.name}&/div&;
ReactDOM.render(&Hello name={'world'} /&, document.getElementById('app'));
index.html:
&div id="app"&&/div&
&!--entry 为一个字符串,这个 chunk 的名字会是 main, 因此这里引入 main.js --&
&script src="build/main.js"&&/script&
启动 webpack-dev-server,打开浏览器这个时候应该能在页面上看到 hello world,这说明工作正常。
4. 拆分框架代码
为了拆分框架代码,我们需要增加一个入口,在这个入口中要包含 react 和 react-dom
module.exports = {
main: 'index.js',
vendor: ['react', 'react-dom']
单单像上面这样配置,打包后会得到 main.js 和 vendor.js,但会发现在 main.js 中依然包含了 react 和 react-dom 的代码,这是因为指定了入口后,webpack 就会从入口文件开始讲整个依赖打包进来,index.js 中引用了 react 和 react-dom 自然会被打包进去。要想达到之前所说的那个效果,还需要借助一个插件 —— CommonsChunkPlugin
5. 使用 CommonsChunkPlugin
这个插件的功能是将多个打包结果中公共的部分抽取出来,作为一个单独的文件。它符合目前的场景,因为 main.js 和 vendor.js 中存在一份公共的代码,那就是 vendor.js 中的内容。(这个说法并不准确,这里只是指 react 和 react-dom 都被打包进了这两个文件)
let webpack = require('webpack');
module.exports = {
main: 'index.js',
vendor: ['react', 'react-dom']
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' // 指定一个希望作为公共包的入口
再进行打包,这个时候会发现 main.js 中的代码不在包含 react 的代码了。看似实现了我们的需求,但真实应用下并没有这么简单,在实际项目中 js 脚本通常都会给添加一个 MD5 的 hash 在后面,形如 app@709dc8ba1d4.js 这样每次打包后,如果文件内容变了,后面的 hash 也会变动。就以上场景,会发现当我们修改了业务代码后,得到的 hash 是不同的,因此每次都会得到两个不同的打包结果。业务代码改变了,拆分出来的框架包也变了,这显然不符合初衷 —— 利用浏览器缓存。
这是因为 webpack 在打包的时候会产生一些运行时代码,比如 __webpack_require__ 、webpackJsonp 等等,这些函数是用来帮助 webpack 完成模块加载等功能的,业务代码的改变会导致业务代码打包后的 hash 值改变,而在 webpack 的运行时代码中实际上是保存了打包后的结果的文件名的,因为它在异步加载模块的时候需要用到。因此,下面需要做的是将 webpack 的运行时代码拆分出来。
修改 plugins 如下,将 name 修改为 names,并增加一个 init 的包名,执行打包,会发现 webpack 的运行时代码都被入该包内。
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'init']
这样以来,修改了业务代码后,vendor 因为只引用了 react 和 react-dom 因此,业务代码的改变不会改变 vendor 这个包的内容,hash 也保持不变。但,也仅仅如此 如果你引用了其他模块,webpack 收集依赖的时候会给每个模块编一个号,引入其他模块会导致模块数改变,也就会导致编号改变,这个时候打包出来的 vendor 还是会改变。
那么到底该如何解决这个问题呢?在官方文档上没有找到解决方案。后面我会继续探索这一问题,找到解决方案后会及时更新到这里,如果你有解决方案,还请不吝赐教,谢谢。
5 收藏&&|&&42
最后一个问题,用dllPlugin来解决,模块不变打出来的包就不会变。
最后一个问题,用dllPlugin来解决,模块不变打出来的包就不会变。
能分享下你的webpack项目结构么?
能分享下你的webpack项目结构么?
chunkHash就好。这个文章比较老了,很多现在都可以处理了。建议大家看下最新的。
chunkHash就好。这个文章比较老了,很多现在都可以处理了。建议大家看下最新的。
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。}

我要回帖

更多关于 extract 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信