运行方法: npx webpack
可在package.json中通过
"scripts": {
"bundle": "webpack --watch"
},
定义bundle为webpack打包项,就可以通过npm run bundle进行打包配置
1、mode模式:
mode: 'production',
// webpack 使用相应模式的内置优化,分为production和development(打包的文件不会压缩在一行显示)
在开发和生产环境中,mode的形式不同,会导致所编译的数据不同
这时我们可以在根路径上新建webpack.dev.js和webpack.prod.js配置其中的参数,
但是production和development模式的很多配置相同,这时我们可以在新建一个webpack.common.js填写公用的数据,然后引入webpack-merge工具融合common.js和本身的参数,引用方法:
npm install webpack-merge --save
然后const merge = require('webpack-merge'),
const commonConfig = require('./webpack.conmon.js')
const devConfig = {mode: 'development'},
module.export = merge(commonConfig,devConfig)
同时在package.json的scripts中:
"scripts": {
"build": "webpack --config webpack.prod.js",
"dev": "webpack-dev-server -config webpack.dev.js"
},
就可以通过npm run build获取生产环境中的打包数据,通过npm run dev获取开发环境中的打包数据
2、entry入口文件,定义需要打包编译的起点
entry: {main: './src/index.js'}
简写entry:'./src/index.js'
打包编译多个文件时:比如
entry:{
main: './src/index.js',
sub: './src/index.js',
}
要在output中配置占位符:filename: ‘[name].js’,//name代表的main、sub定义的名称
3、output输出文件
const path = require('path')
output: {
publicPath: 'http://cdn.cn', //加入此可以在打包的js文件前添加一个cdn域名
filename: 'bundle.js',//定义输出文件的文件名
path: path.resolve(__dirname,'bundle') //定义输出文件文件夹的绝对路径
}
4、loader用于对模块的源代码进行转换,webpack本身只识别打包编译js文件,对于其他的文件要进行loader的配置
module: {
rules: [{ //webpack只能识别js结尾的文件打包编译,对于其他的文件打包编译要进行以下配置
test: '/\.jpg$/',
use: {
loader: 'file-loader'
}
}, {
test: '/\.vue$/',
use: {
loader: 'vue-loader'
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' }, //挂在在dom节点上
{
loader: 'css-loader', //合并所有的css样式
options: {
modules: true,//定义模块化,
importLoaders: 2 //用于配置「css-loader 作用于 @import 的资源之前」有多少个 loader
}
},
{loader: 'sass-loader'},
{loader: 'postcss-loader'} //给css加上浏览器前缀,提升性能
}]
},
注意: 引入postcss文件时,要添加postcss.config.js文件
module.exports = {
plugins: [
require('autoprefixer')引入autoprefixer插件(npm install autoprefixer --save)
]
}
1、HtmlWebpackPlugin,自动生成一个打包过后的html文件,并将打包好的js引入到该文件中,安装npm install --save-dev html-webpack-plugin,使用
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [new HtmlWebpackPlugin({
template: 'src/index.html' //定义打包后的模板,因为new HtmlWebpackPlugin只会引入js文件,dom通过这种模板格式引入
})],
2、cleanWebpackPlugin,打包过程中在output中打包输出之前的js文件,例如bundle.js,如果改变filename的名称时,再次进行打包的话,之前的bundle.js会存在,cleanWebpackPlugin就是在打包前删除之前打包文件数据的一个插件
安装方法:npm install clean-webpack-plugin --save
使用方法:
const CleanWebpackPlugin = require('clean-webpack-plugin')
plugins: [new HtmlWebpackPlugin({
template: 'src/index.html'
}), new CleanWebpackPlugin(['bundle'])], //每次打包前删除bundle文件夹下的文件
output: {//输出文件
filename: 'bundle.js',//定义输出文件的文件名
path: path.resolve(__dirname,'bundle') //定义输出文件文件夹的绝对路径
}
6、devtool 此选项控制是否生成,以及如何生成 source map。
devtool: 'cheap-module-eval-source-map ',
//当代码运行错误时,在控制台中会提示打包后文件中代码出错的位置
//定义devtool下的source-map会提示打包时出错的代码在源代码中位置
//一般mode为development模式下,devtool为cheap-module-eval-source-map;在production模式下一般使用cheap-module-source-map
//其中cheap指的是只提示多少行出错了,而不提示列;module指的是除了源代码中的错误,其他的loader中的错误也会进行提示;eval指的是将错误代码以eval的方式进行打包
7、devServer(webpack-dev-server 能够用于快速开发应用程序),可以给文件一个端口号
devServer: {
contentBase: './bundle', //所有来自./bundle目录的文件都做 gzip 压缩和提供为服务:对应output输出文件的名称
open: true, //运行devServer时自动进入浏览器打开html文件
port:3030 //定义端口号的数字
},
"scripts": {
"bundle": "webpack",
"start": "webpack-dev-server"
},//在package.json中定义start为webpack-dev-server,就可以通过npm run start运行文件
8、模块热替换(hot module replacement)
它允许在运行时更新各种模块,而无需进行完全刷新
例如更改css样式时,不刷新页面,直接更改所对应的css样式
devServer: {
contentBase: './bundle',
open: true,
hot: true,
hotOnly: true
},
引入:const webpack = require('webpack')
plugins: [
new HtmlWebpackPlugin({template: 'src/index.html'}),
new CleanWebpackPlugin(['bundle']),
new webpack.HotModuleReplacementPlugin()
],
if (module.hot) {
module.hot.accept('./library.js', function() {
// 使用更新过的 library 模块执行某些操作...
})
当存在多个js文件引入时,填写你所需要更新的js名称,在加载时更新
}
9、babel (es6语法转化为es5语法)
安装:
npm install --save-dev babel-loader @babel/core //打通es6转化为es5的桥梁
npm install @babel/preset-env --save-dev //包含了所有es6转化为es5的代码
在module下
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
"presets": [["@babel/preset-env",{
useBulitIns: 'usage' ,//babel-polyfill进行es6转化时,不是将所有的都转化,只转化业务代码中的es6语法,会减少打包的内存
}]]
}
上面配置只能将普通的逻辑代码转化为es5语法,要想将语法也转化为es5代码,需要安装babel-polyfill插件。
安装方法: npm install --save @babel/polyfill
import "@babel/polyfill";在业务代码中引入babel-polyfill
在写类或者库时,如果使用babel-polyfill会污染全局环境,这时候要使用@babel/plugin-transform-runtime这个插件,就不会污染全局环境:
引用@babel/plugin-transform-runtime的方法:
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
配置:{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
// "presets": [["@babel/preset-env",{
// useBulitIns: 'usage' ,//babel-polyfill进行es6转化时,不是将所有的都转化,只转化业务代码中的es6语法,会减少打包的内存
// }]]
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 2,
//改为2时,需要额外安装npm install --save @babel/runtime-corejs2
//core-js是什么
//它是JavaScript标准库的polyfill
//它尽可能的进行模块化,让你能选择你需要的功能
//它可以不污染全局空间
//它和babel高度集成,可以对core-js的引入进行最大程度的优化
"helpers": true,
"regenerator": true,
"useESModules": false,
"version": "7.0.0-beta.0"
}
]
]
} ,
可以在根路径创建一个babelrc文件夹,将options中的数据放进去,简化代码
10、Tree shaking 只支持es module引入,含义是引入一个模块时,只引入需要的代码,比如说element-ui,只引入el-button,import el-button from ‘element-ui’
如果开发环境mode: ''production"时,只需在package.json中配置
"sideEffects": false
表示不需要进行配置的文件,可用数组添加,例如[*.css]
如果开发环境mode: 'development’时,就需要的export module下配置
optimization: {
usedExports: true
},
并在package.json中配置"sideEffects": false
11、Code Splitting代码分割
含义:代码分割(Code Split)主要出于两种原因:一是减少代码重复,比如在多页面的应用中,如果多个页面都同时引用了某些module的情况;二是支持缓存,比如第三方库通常是不会怎么变的,将他们单独抽离出来有利于浏览器缓存。
webpack中实现代码分割的两种方式:
1、同步代码: 在webpack.config.js中定义
optimization: {
splitChunks: {
chunks: 'all'
}
},
2、异步代码:(import异步引入的),无需进行配置,会自动进行代码分割
例如:
function getfull() {
return import(/*webpackChunkName='losh' */ axios).then(()=>{
console.log('成功')
})
/*webpackChunkName=‘losh’ */ axios 魔法注释,更改打包后文件的名称
动态引入组建的插件:npm install --save-dev @babel/plugin-syntax-dynamic-import
并把其配置在babelrc文件下:
plugins: [" @babel/plugin-syntax-dynamic-import"]
optimization: {
usedExports: true,
splitChunks: {
chunks: "async", //异步组建分割,all全部分割,initial同步组建分割
minSize: 30000, //30kb以上的异步文件分割
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: false, //打包后的js不包含默认的vendors前缀
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
},
12、打包分析,Preloading,Prefetching
https://blog.csdn.net/purple_lumpy/article/details/100073807