从启动webpack构建到输出结果经历了一系列过程:javascript
指示 webpack 应该使用哪一个模块,来做为构建其内部依赖图的开始css
entry: './src/app.js'
html
等同于下面写法:vue
entry: {
main: './src/app.js'
}
复制代码
分离 应用程序(app) 和 第三方库(vendor) 入口java
entry: {
app: './src/main.js',
vendor: './src/jquery.js'
}
复制代码
这告诉咱们 webpack 从 main.js 和 jquery.js 开始建立依赖图(dependency graph)。这些依赖图是彼此彻底分离、互相独立的。node
webpack 编译时的基础目录,entry和loader 会相对于此目录查找react
默认值为当前目录,不建议修改jquery
告诉 webpack 在哪里输出它所建立的 bundleswebpack
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: 'js/[name].js'
}
复制代码
用于指定打包后的文件须要加载的外部资源(如图片、js、css等)的跟路径git
默认值是一个空字符串 "",一般设置成"/"
静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径
{ name: 'imgs/[name].[ext]' }
// 那么图片最终的访问路径为
output.publicPath('/') + 'imgs/[name].[ext]' = '/imgs/[name].[ext]'
复制代码
new ExtractTextPlugin('css/[name].[contenthash:10].css')
// html中加载css打包后代码
<link href="/css/app.9502b0c565.css" rel="stylesheet">
复制代码
<script type="text/javascript" src="/js/runtime.4ece365fd5.js"></script>
复制代码
打包文件输出的目录
建议绝对路径;默认值为当前路径。
path 中用使用 [hash] 模板可用于版本回归
output: {
path: path.resolve('./dist/[hash:8]/')
}
复制代码
loader 让 webpack 可以去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)
注意:module.loaders 改成 module.rules;链式loader
module: {
loaders: [{
test: /\.less$/,
loader: "style!css!less"
})
}
复制代码
module: {
rules: [{
test: /\.less$/,
use: [
"style-loader",
"css-loader",
"less-loader"
]
}]
}
复制代码
{
test: /\.(gif|png|jpe?g|svg)$/,
use: [{
loader: 'file-loader',
options:{}
}]
}
复制代码
默认输出到output的根目录下,name为32为hash值
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
name | {String | Funciton} | [hash].[ext] | 自定义文件名 |
placeholders
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
[ext] | {String} | file.extname | 资源扩展名 |
[name] | {String} | file.name | 资源名 |
[path] | {String} | file.dirname | 资源路径 |
[hash] | {String} | md5 | 内容的哈希值 |
对file-loader的扩展,能够设置小图片转换base64图片
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit:5000,
name: 'img/[name].[ext]?[hash]'
}
}
]
}
复制代码
在全局上下文(global context)执行一次 JS脚本,就像你在网页上经过<script>把它们引进来同样。
因为浏览器只能读懂ES5语法,须要babel将ES2015+语法编译为ES5语法
npm install babel-loader babel-core babel-preset-env webpack
{
test: /\.js$/,
use: {
loader: 'babel-loader',
exclude: /node_modules/,
options: {}
}
}
复制代码
options
minimize:true 压缩html文件
将内联的 SVG/MathML 文件转换为 HTML。在应用于图标字体,或将 CSS 动画应用于 SVG 时很是有用
{
test: /\.html$/,
use: [
'html-loader',
'markup-inline-loader'
]
}
复制代码
html中使用:
<img markup-inline src="./_images/camera.svg" />
<img data-markup-inline src="./_images/camera.svg" />
css代码放入js代码里再加入到html里
获得css代码
获得css文件
后处理css文件,对css文件作语法分析,真正的核心操做,依赖于postcss庞大的插件群体 postcss插件
好比css的语法验证,压缩,支持变量和混入语法
postcss: function(webpack) {
return [
postcssImport({
addDependencyTo: webpack
}),
autoprefixer
]
}
复制代码
loader 被用于转换某些类型的模块,而插件则能够用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到从新定义环境中的变量
new htmlWebpackPlugin(options)
复制代码
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
title | {String} | `` | 用于生成的HTML文档的标题 |
filename | {String} | 'index.html' | 生成html的文件名 |
template | {String} | `` | 模版路径及文件名(路径相对与output.context) |
inject | {Boolean|String} | true | 当传递true或'body'全部JavaScript资源将被放置在正文元素的底部。'head'将脚本放置在head元素中,false不会将脚本放进html中 |
favicon | {String} | `` | 将给定的图标路径添加到输出HTML |
minify | {Boolean|Object} | true | 缩小输出html html-minifier |
hash | {Boolean} | false | true:将webpack全部包含的脚本和CSS文件附加一个独特的编译哈希。这对缓存清除很是有用 |
cache | {Boolean} | true | 仅在文件被更改时才发出文件 |
showErrors | {Boolean} | true | 错误细节将写入HTML页面 |
chunks | {?} | ? | 容许添加的chunk名 |
chunksSortMode | {String|Function} | auto | 容许控制chunk在被包含到HTML以前应该如何排序。容许的值是'none'不分类 | 'auto'按块ID排序 | 'dependency'经过其“父项”属性对块之间的依赖关系进行排序 | 'manual' | {Function} |
excludeChunks | {String} | `` | 容许您跳过一些chunk |
xhtml | {Boolean} | false | 若是true将link标签呈现为自动关闭(符合XHTML) |
chunksSortMode: function (chunk1, chunk2) {
var order = ['common', 'public', 'index'];
var order1 = order.indexOf(chunk1.names[0]);
var order2 = order.indexOf(chunk2.names[0]);
return order1 - order2;
}
复制代码
webpack 把全部的资源都当成了一个模块, CSS,Image, JS 字体文件资源, 都打包到一个 bundle.js 文件中
它将*.css输入块中的全部必需模块移动到单独的CSS文件中
new ExtractTextPlugin([id: string], filename: string, [options])
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",//编译后用什么loader来提取css文件
publicPath:, //重写此 loader 的 publicPath 配置
use: "css-loader" //须要什么样的loader去编译文件
})
}
]
}
复制代码
CopyWebpackPlugin([
{
context: 'global/img',
from: '**/*',
to:'img/common'
},
{
from: 'img',
to:'img'
},
{
from :'global/lib/es5-shim-sham.js'
}
])
复制代码
from 定义要拷贝的源目录.
to 定义要拷盘的目标目录.
context 上下文.
flatten 只拷贝文件无论文件夹 默认是false.
ignore 忽略拷贝指定的文件 能够用模糊匹配.
force 强制覆盖先前的插件 可选 默认false.
new webpack.optimize.UglifyJsPlugin(options)
复制代码
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
test | {RegExp|Array<RegExp>} | /.js$/i | 匹配文件 |
include | {RegExp|Array<RegExp>} | undefined | 包含目录 |
exclude | {RegExp|Array<RegExp>} | undefined | 非匹配目录 |
cache | {Boolean|String} | false | 启用文件缓存;cache: 'path/to/cache' |
parallel | {Boolean|Number} | false | 使用多进程并行运行来提升构建速度 |
sourceMap | {Boolean} | false | 使用源映射将错误消息位置映射到模块(这会减慢编译速度) ⚠️ cheap-source-map 选项不适用于这个插件 |
uglifyOptions | {Object} | {...defaults} | uglify 选项 |
webpack.optimize.UglifyJsPlugin()遇到的 Unexpected token: operator (>) from UglifyJs
问题可使用 uglifyjs-webpack-plugin插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
复制代码
new CleanWebpackPlugin(['./dist'])
webpack将多个模块打包以后的代码集合称为chunk
将公共js代码提取到单独文件里
new webpack.optimize.CommonsChunkPlugin(options)
module.exports = {
entry: {
main1: '/src/main1.js',
main2: '/src/main2.js',
jquery:["jquery"],
vue:["vue"]
},
plugins: [
new CommonsChunkPlugin({
name: ["common",'jquery','vue'],//对应于上面的entry的key
minChunks:2
})
]
};
复制代码
打包后jquery和vue会生成独立chunk,main1和main2中的公共业务模块会打包到common.js中;minChunks为infinity时,公共业务模块会分别打包到main1.js和main2.js中
webpack用插件CommonsChunkPlugin进行打包的时候 将符合引用次数(minChunks)的模块打包到name参数的数组的第一个块里(chunk),而后数组后面的块依次打包,最后一个块包含webpack生成的在浏览器上使用各个块的加载代码
new webpack.HotModuleReplacementPlugin()
复制代码
devServer: {
hot: true // 激活服务器的HMR
}
复制代码
在不一样系统环境下设置变量
css-loader?minimize
去除css文件里有不少空格和tab
借助es6 import export
语法静态性的特色来删掉export可是没有import过的东西
"presets": [
[
"es2015",
{
"modules": false
}
]
]
复制代码
new UglifyJsPlugin({
// 最紧凑的输出
beautify: false,
// 删除全部的注释
comments: false,
compress: {
// 在UglifyJs删除没有用到的代码时不输出警告
warnings: false,
// 删除全部的 `console` 语句
// 还能够兼容ie浏览器
drop_console: true,
// 内嵌定义了可是只用到一次的变量
collapse_vars: true,
// 提取出出现屡次可是没有定义成变量去引用的静态值
reduce_vars: true,
}
})
复制代码
imagemin-webpack-plugin
压缩图片module.exports = {
resolve: {
modules: [path.resolve(__dirname, 'node_modules')]
}
};
复制代码
{
test: /\.js$/,
loader: 'babel-loader',
include: path.resolve(__dirname, 'src')
}
复制代码
babel编译过程很耗时,好在babel-loader提供缓存编译结果选项,在重启webpack时不须要创新编译而是复用缓存结果减小编译流程。babel-loader缓存机制默认是关闭的,打开的配置以下:
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
}
复制代码
resolve.alias 配置路径映射。 发布到npm的库大多数都包含两个目录,一个是放着cmd模块化的lib目录,一个是把全部文件合成一个文件的dist目录,多数的入口文件是指向lib里面下的。
默认状况下webpack会去读lib目录下的入口文件再去递归加载其它依赖的文件这个过程很耗时,alias配置可让webpack直接使用dist目录的总体文件减小文件递归解析。配置以下:
module.exports = {
resolve: {
alias: {
'moment': 'moment/min/moment.min.js',
'react': 'react/dist/react.js',
'react-dom': 'react-dom/dist/react-dom.js'
}
}
};
复制代码
module.noParse
配置哪些文件能够脱离webpack的解析。 有些库是自成一体不依赖其余库的没有使用模块化的,好比jquey、momentjs、chart.js,要使用它们必须总体所有引入。
webpack是模块化打包工具彻底没有必要去解析这些文件的依赖,由于它们都不依赖其它文件体积也很庞大,要忽略它们配置以下:
module.exports = {
module: {
noParse: /node_modules\/(jquey|moment|chart\.js)/
}
};
复制代码