Webpack学习笔记
webpack - 项目优化
webpack实现原理
webpack - loader
webpack - plugin
webpack - 项目优化2
plugin本质上是基于webpack内部的发布订阅(tapable)上的一群钩子,来做打包个性化的
css提取至单文件 mini-css-extract-plugin
{
test: /\.png$/,
use: {
loader: 'url-loader',
options: {
publicPath: 'http://www.xx.com/'
// 所有图片使用cnd地址
}
}
}
{
test: /\.less$/,
use: [ MiniCssExtractPlugin.loader, 'css-loader', 'less-loader' ] //'style-loader',
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/haha_main.css'
}),
此plugin上自带一个loader,以取代style-loader把css提取至单独文件
打包后生成dist/css/haha_main.css
,并在index.html中自动引入了此css
-
css自动hack PostCss
postcss-loader需要比css-loader先执行(写在它之后)。它需要配置文件
// postcss.config.js
module.exports = {
plugins: [require('autoprefixer')]
}
autoprefixer是postcss的插件,用于解析CSS并使用Can I Use中的值向CSS规则添加供应商前缀 。它是 Google 推荐的,并在Twitter和阿里巴巴中使用。
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader, //'style-loader',
'css-loader',
'postcss-loader',
'less-loader'
]
},
打包后类似transform的属性添加了前缀 -webkit- 等
代码优化压缩 optimize-css-assets-webpack-plugin 和 uglifyjs-webpack-plugin
mode: 'production',
optimization: { // 优化项
minimizer: [
new OptimizeCssPlugin(), // 压缩css
new uglifyjsPlugin() // 压缩js
]
},
production下js默认是被压缩的,但配置此优化项后,需要手工添加 uglifyjs-webpack-plugin 插件,js才会被同时压缩
development下优化项(optimization)无效
ES6 转 ES5
- babel-loader
- @babel/core // 核心模块
- @babel/preset-env// 转化模块
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: { presets: ['@babel/preset-env'] } // es6->es5
}
}
// 项目入口文件
let fn = arg => console.log(arg)
fn('哇哈哈哈哈哈~~~')
打包后箭头函数变成了正常函数。如果使用了es7或更新的特性(如class中静态属性),babel会提示你还需要添加新插件
class A {
a = 2
}
let temp = new A()
console.log('------', temp.a)
// ------ 打包 ------
Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.
options: {
presets: ['@babel/preset-env'], // es6->es5
plugins: [
'@babel/plugin-proposal-class-properties' // 支持表态类属性
]
}
class被转为 _classCallCheck ,代码可直接在浏览器中运行
清理目录 clean-webpack-plugin
plugins: [
new CleanWebpackPlugin('./dist'),
],
复制目录 copy-webpack-plugin
plugins: [
new CopyPlugin([
{ from: 'source', to: 'dest' },
{ from: 'other', to: 'public' },
]),
],
编译时的全局变量 DefinePlugin
new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify('http://dev.example.com') // 必须 "'str'"
});
忽略插件 IgnorePlugin
plugins: [
new webpack.IgnorePlugin(/\.\/locale/, 'moment'),
],
忽略moment/locale下所有代码,所以在项目中调用moment.locale('zh-cn')
语言包无法生效,需要手动引入语言包
import('moment/locale/zh-cn.js')
动态插件库 DLLPlugin 和 DLLReferencePlugin
将一些功能打包成dll,在其它项目中使用DLLReferencePlugin引用以减少打包时间和包大小
let Vue = require('vue')
new Vue.default({
data: {
message: 'Hello Vue!'
},
render (h) {
return h('div', this.message)
}
}).$mount('#app')
将以上文件打包共 249K。下面使用DLLPlugin将vue单独打包
// webpack.dll.js
let path = require('path')
let webpack = require('webpack')
module.exports = {
mode: 'development',
entry: {
vue: ['vue'],
},
output: {
filename: '_dll_vue.js',
path: path.resolve(__dirname, 'dist'),
library: '_DLL_VUE',
libraryTarget: 'var' // commonjs this ...
},
plugins: [
new webpack.DllPlugin({
name: '_DLL_VUE',
path: path.resolve(__dirname, 'dist', 'manifest.json')
})
]
}
webpack --config webpack.dll.js
打包后生成 _dll_vue.js、manifest.json 文件
js文件顶部多行代码var _DLL_VUE =
- var
var _DLL_VUE =
- this
this["_DLL_VUE"] =
- commonjs
exports["_DLL_VUE"] =
- ...
在模板文件中使用标签引入 _dll_vue.js,webpack.config.js中添加plugin:
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'dist', 'manifest.json')
})
打包后bundle.js共 5.02 K。vue被单独在html中引入了