Open Christian-freedom opened 7 years ago
例子1:http://blog.csdn.net/github_26672553/article/details/52280655
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');
var extractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
// entry是入口文件,可以多个,代表要编译那些js
//entry:['./src/main.js','./src/login.js','./src/reg.js'],
entry:
{
'main':'./src/main.js',
'user':['./src/login.js','./src/reg.js'],
'index':['./src/index.js']
},
externals:{
'jquery':'jQuery'
},
module:{
loaders:[
// {test:/\.css$/,loader:'style-loader!css-loader'},
{test:/\.css$/,loader:extractTextPlugin.extract('style','css')}
],
},
output:{
path: __dirname+'/build/js', // 输出到那个目录下(__dirname当前项目目录)
filename:'[name].js' //最终打包生产的文件名
},
plugins:[
new HtmlWebpackPlugin({
filename: __dirname+'/build/html/login-build.html',
template:__dirname+'/src/tpl/login.html',
inject:'body',
hash:true,
chunks:['main','user','common.js'] // 这个模板对应上面那个节点
}),
new HtmlWebpackPlugin({
filename: __dirname+'/build/html/index-build.html',
template:__dirname+'/src/tpl/index.html',
inject:'body',
hash:true,
chunks:['index','common.js'] // 这个模板对应上面那个节点
}),
// css抽取
new extractTextPlugin("[name].css"),
// 提供公共代码
new webpack.optimize.CommonsChunkPlugin('common.js'), // 默认会把所有入口节点的公共代码提取出来,生成一个common.js
]
};
CommonsChunkPlugin的使用如下:
new webpack.optimize.CommonsChunkPlugin({
//这段代码的意思是,从上面的entry中的三个入口文件,生成的最终的三个bundles文件,main.js和
user.js和index.js三个文件中,提取出一个在三个文件中都存在的代码,作为一个公共块common.js
name:'common', // 注意不要.js后缀
chunks:['main','user','index']
}),
这段代码的意思是,从上面的entry中的三个入口文件,生成的最终的三个bundles文件,main.js和 user.js和index.js三个文件中,提取出一个在三个文件中都存在的代码,作为一个公共块common.js
通过CommonsChunkPlugin,我们把公共代码专门抽取到一个common.js,这样业务代码只在index.js,main.js,user.js。
这两个关于CommonsChunkPlugin的解释更加详细一点:
https://segmentfault.com/q/1010000009070061
http://www.jianshu.com/p/2b81262898a4
//////////////////////////第一:[name]的含义///////////////////////////////////////
这是一个我们需要使用的公共组件foo.js
//foo.js
export let foo = 123;
---------------------------情况A:只有一个入口文件----------------------------
//入口文件
entry: {
page1: './src/js/entry1.js'
}
//提取公共chuck的name
new CommonsChunkPlugin({ name: 'vendor' })
然后我们引入foo.js
//entry1.js
import { foo } from './components/foo.js';
console.log(`${foo}-entry1`);
结果:foo.js会和entry1被打包到一起变成page1,webpack的运行文件会被抽离出来成为vendor.js
理解=>{
这个结果的意思是:把webpack运行时(Runtime)代码单独的提取出来,创建了一个
vendor.js文件
}
---------------------------情况B:两个入口文件----------------------------
//入口文件
entry: {
page1: './src/js/entry1.js',
page2: './src/js/entry2.js'
}
//提取公共chuck的name
new CommonsChunkPlugin({ name: 'vendor' })
然后entry1和entry2都引入foo.js
//entry1.js
import { foo } from './components/foo.js';
console.log(`${foo}-entry1`);
//entry2.js
import同上
console.log(`${foo}-entry2`);
结果:entry1和entry2会分别被打包成page1、page2,webpack运行文件和foo.js会被抽取成为vendor
理解=>{
这个结果的意思是:因为entry1和entry2两个文件都引用了foo.js这个文件,所以正常情况下,
page1中会有entry1和foo.js的代码,而page2中会有entry2和foo.js的代码。而webpack的运行时代码,
肯定在page1和page2中都有,所以如果要提取出共同的东西也就是vendor。那么最终vendor就会把page1和page2中的共同的东西都提取出来,也就是foo.js和两个文件中存在的webpack运行时代码,这样
生成了一个vendor.js
}
---------------------------情况C:有的入口没引用foo.js----------------------------
//入口文件
entry: {
page1: './src/js/entry1.js',//引用foo.js
page2: './src/js/entry2.js',//引用foo.js
page3: './src/js/entry3.js',//新增入口,不引用foo.js
}
//提取公共chuck的name
new CommonsChunkPlugin({ name: 'vendor' })
结果:会生成page123三个js文件,并且foo.js会被包含在page1和page2中,并没有被抽离出来。
vendor.js里则只有webpack运行文件,等于公共模块功能未实现.
此时就体现出在入口中指定公共模块的重要性了,就是下面的情况D
---------------------------情况D:指定公共文件入口----------------------------
//入口文件
entry: {
page1: './src/js/entry1.js',//不引用foo.js
page2: './src/js/entry2.js',//引用foo.js
page3: './src/js/entry3.js',//引用foo.js
'vendor': ['./src/js/components/foo.js']
}
//提取公共chuck的name
new CommonsChunkPlugin({ name: 'vendor' })
此时我们指定了新入口vendor,并且它指向foo.js
三个入口有的引用了foo,有的则没有
结果:不管entry1/2/3是否引用foo,foo.js和webpack运行文件都被抽取出来成为vendor.
所以此方式可以用来抽取第三方类库和框架,这样每一个入口文件无论是否调用它们,都不会将它们重复打包进去,例如:
'vendor': ['react','jquery','others']
---------------------------情况E:name指定的chunk不存在----------------------------
条件:
1、入口文件里没写vendor:[...]
2、entry1和entry2都没引用任何文件
结果:那么这样会发现生成的vendor.js里是webpack运行文件加一个([])空chunk;
综上: name的意思就是,提取出来的东西,公共的东西就是name.js
//////////////////////////第二:[filename]的含义///////////////////////////////////////
这个很简单,filename就是打包出来的公共模块的实际名称
1、当filename未定义,就默认使用name的名称作为打包后文件名2、当filename已指定,就用它指定的名称了
//////////////////////////第三:[minchunks]////////////////////////////////////
minchunks表示模块抽取的最小被调用次数,也就是说minchunks:10,那么这个chunk最少需要被调用10次,webpack才会把它当做一个公共模块抽取出来。
//////////////////////////*第三:[chunks]////////////////////////////////////
前面的都是把公共模块打包成了一整块vendor.js,那么如果需要从这个vendor.js中再抽取就需要用到chunks选项
意思就是:已经从自己写的模块中抽取出了公共的模块,这个公共的模块叫做vendor.js,然后我还想从这个公共的模块中再次抽取东西,比如我想把webpack的运行时代码抽取出来,那么就使用chunks这个参数,那么比如:
//首先从所有的自己定制的模块中提取出公共的模块
new CommonsChunkPlugin({ name: 'vendor' }),
//从上面生成的公共的模块vendor.js中,再次提取公共的东西,这里提取的就是webpack运行时
代码,因为这个东西每次编译的时候都会改变,所以把它单独的提取出来。
所以下面的东西的意思是:从vendor.js这个块中提出公共的运行时代码到manifest.js文件中
new CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor'] }),
//入口文件
entry: {
page1: './src/js/entry1.js',
page2: './src/js/entry2.js',
'vendor': ['./src/js/components/foo.js']
}
//公共模块
new CommonsChunkPlugin({ name: 'vendor' }),
new CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor'] }),
结果:foo.js和webpack的运行文件会先被生成vendor.js,然后webpack的运行文件会被从vendor中再次抽出,生成一个manifest.js文件
上面的写法也等于:
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest'],
}),
解决webpack运行时代码的问题: webpack打包第三方类库的正确姿势:https://segmentfault.com/a/1190000005828579
================没看====================
webpack代码分割技巧:http://www.tuicool.com/articles/UZRF3qM
看完这篇就看懂了很多webpack脚手架:https://segmentfault.com/a/1190000007972133
================没看====================
/**
* Plugin: CommonsChunkPlugin
* Description: Shares common code between the pages.
* It identifies common modules and put them into a commons chunk.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
* See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
*/
new CommonsChunkPlugin({
name: 'polyfills',
chunks: ['polyfills']
}),
/**
* This enables tree shaking of the vendor modules
*/
// new CommonsChunkPlugin({
// name: 'vendor',
// chunks: ['main'],
// minChunks: module => /node_modules/.test(module.resource)
// }),
/**
* Specify the correct order the scripts will be injected in
*/
// new CommonsChunkPlugin({
// name: ['polyfills', 'vendor'].reverse()
// }),
// new CommonsChunkPlugin({
// name: ['manifest'],
// minChunks: Infinity,
// }),
这是angular starter中的webpack.common.js中的代码。原来是全部放开的,但是今天看到的版本是,作者注释掉了其他的,只是保留了:
new CommonsChunkPlugin({
name: 'polyfills',
chunks: ['polyfills']
}),
这段代码的意思是:从polyfills.js中提取出一个叫做polyfills.js的公共模块。 而入口的配置是:
entry: {
'polyfills': './src/polyfills.browser.ts',
'main': AOT ? './src/main.browser.aot.ts' :
'./src/main.browser.ts'
},
CommonsChunkPlugin
new webpack.optimize.CommonsChunkPlugin(options)
CommonsChunkPlugin 插件,是一个可选的用于建立一个独立文件(又称作 chunk)的功能,这个文件包括多个入口 chunk 的公共模块。通过将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存起来到缓存中供后续使用。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。配置
webpack1 构造函数
new webpack.optimize.CommonsChunkPlugin(options, filenameTemplate, selectedChunks, minChunks)
不再被支持。请使用相应的选项对象。例子
公共chunk 用于 入口chunk (entry chunk)
生成一个额外的 chunk 包含入口chunk 的公共模块。
你必须在 入口chunk 之前加载生成的这个 公共chunk:
明确第三方库 chunk
将你的代码拆分成公共代码和应用代码。
提示:结合长期缓存,你可能需要使用这个插件去避免 公共chunk 改变。 你也需要使用 records 去保持稳定的模块 id。
将公共模块打包进父 chunk
使用代码拆分功能,一个 chunk 的多个子 chunk 会有公共的依赖。为了防止重复,可以将这些公共模块移入父 chunk。这会减少总体的大小,但会对首次加载时间产生不良影响。如果预期到用户需要下载许多兄弟 chunks(例如,入口 trunk 的子 chunk),那这对改善加载时间将非常有用。
额外的异步 公共chunk
与上面的类似,但是并非将公共模块移动到父 chunk(增加初始加载时间),而是使用新的异步加载的额外公共chunk。当下载额外的 chunk 时,它将自动并行下载。
给 minChunks 配置传入函数
你也可以给 minChunks 传入一个函数。这个函数会被 CommonsChunkPlugin 插件回调,并且调用函数时会传入 module 和 count 参数。
module 参数代表每个 chunks 里的模块,这些 chunks 是你通过 name/names 参数传入的。 module has the shape of a NormalModule, which has two particularly useful properties for this use case:
count 参数表示 module 被使用的 chunk 数量。
当你想要对 CommonsChunk 如何决定模块被打包到哪里的算法有更为细致的控制, 这个配置就会非常有用。
正如上面看到的,这个例子允许你只将其中一个库移到一个分开的文件当中,当而仅当函数中的所有条件都被满足了。
This concept may be used to obtain implicit common vendor chunks:
In order to obtain a single CSS file containing your application and vendor CSS, use the following minChunks function together with ExtractTextPlugin:
Manifest file
To extract the webpack bootstrap logic into a separate file, use the CommonsChunkPlugin on a name which is not defined as entry. Commonly the name manifest is used. See the code splitting libraries guide for details.
Combining implicit common vendor chunks and manifest file
Since the vendor and manifest chunk use a different definition for minChunks, you need to invoke the plugin twice:
More Examples
Common and Vendor Chunks Multiple Common Chunks Multiple Entry Points with Commons Chunk