Webpack
初始化操作
-
初始化 package.json:
npm init
-
下载安装webpack:(webpack4以上的版本需要全局/本地都安装webpack-cli)
全局安装:
cnpm i webpack webpack-cli -g
本地安装:
cnpm i webpack webpack-cli -D
创建 src 下的 js 等文件后,不需要配置 webpack.config.js 文件,在命令行就可以编译打包。
指令:
- 开发环境:
webpack ./src/index.js -o ./build/built.js --mode=development
webpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js 整体打包环境,是开发环境
-
生产环境:
webpack ./src/index.js -o ./build/built.js --mode=production
webpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js 整体打包环境,是生产环境
结论:
- webpack 本身能处理 js/json 资源,不能处理 css/img 等其他资源
- 生产环境和开发环境将 ES6 模块化编译成浏览器能识别的模块化,但是不能处理 ES6 的基本语法转化为 ES5(需要借助 loader)
- 生产环境比开发环境多一个压缩 js 代码
- 开发环境:
1.1-5大模块
entry
用来配置打包入口
output
output:{
filename: '',//打包后生成的文件名
path: ''//打包后输出路径
}
打包后输出路径以及文件名
module
loader的配置
rules: [
{
//test是匹配关键字资源,exclude是排除关键字资源
test: /\.(css|less)$/, //匹配css或者less后缀的文件
//使用的loader
use: [
//执行顺序从下而上依次执行
'style-loader',
'css-loader',
'less-loader'
]
},
{
exclude: /\.(css|less)$/, //排除css或者less后缀的文件
loader: 'file-loader'
}
]
plugins
plugins: [
// 详细plugins的配置,处理html资源
new htmlWebpackPlugin({
template:resolve(__dirname, 'src/index.html'),
})
],
mode
用来选择当前webpack打包的模式
mode: 'development'//开发环境
1.2-devServer
//开发服务器 devServer 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
//特点,只会在内存中编译打包,不会有任何输出
//启动devServer: npx webpack-dev-server
devServer: {
contentBase: resolve(__dirname, 'build'),
//启动gzip压缩
compress: true,
//端口号
port: 3000,
//自动打开浏览器
open: true
}
启动指令npx webpack-dev-server
1.3-基本构建webpack
const { resolve } = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
//入口起点
entry: './src/index.js',
//输出
output: {
//输出文件名
filename: 'built.js',
//输出路径
path: resolve(__dirname, 'build')
},
//loader的配置
module: {
rules: [
//详细loader配置
{
//资源匹配,匹配less/css文件
test: /\.(le|c)ss$/,
use: [
//执行顺序从下到上依次执行
'style-loader',
'css-loader',
'less-loader'
]
},
//处理图片资源
{
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8*1024,
name: '[hash:10].[ext]',
//关闭es6模块
esModule: false
}
},
//处理html中img资源
{
test: /\.html$/,
loader: 'html-loader'
},
{
//排除其他资源
exclude: /\.(css|js|html|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
},
]
},
// plugins的配置
plugins: [
// 详细plugins的配置,处理html资源
new htmlWebpackPlugin({
template:resolve(__dirname, 'src/index.html'),
})
],
//模式
mode: 'development',//开发环境
//开发服务器 devServer 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
//特点,只会在内存中编译打包,不会有任何输出
//启动devServer: npx webpack-dev-server
devServer: {
contentBase: resolve(__dirname, 'build'),
//启动gzip压缩
compress: true,
//端口号
port: 3000,
//自动打开浏览器
open: true
}
}
1.4生产环境的webpack配置
当一个文件要被多个loader处理,那要指定loader执行的先后顺序:
先执行eslint 在执行babel
注意兼容性处理,js语法支持
兼容性处理如css的浏览器,兼容各大浏览器。js语法支持,配置babel以支持es6等
//优先执行
enforce: 'pre'
1.5webpack优化配置
1.5.1:Hot Module Replacement(热更新)
一个模块发送变化,只会改变当前模块,不会修改其他的模块
开启热更新
tips
style-loader内部实现了热更新,
js文件: 默认不能使用hmr功能,要修改js代码,添加hmr的代码
html文件: 默认不能使用hmr功能,同时会导致html无法热更新
解决,修改entry入口,将html文件引入
entry: ['./src/js/index.js','./src/index.html']
devServer: {
hot:true
}
1.5.2:source-map
提供源代码到构建后代码映射的技术(如果构建后代码出错,可以通过source-map进行映射查找源代码)
开启
devtool: 'source-map'
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
source-map
:外部
错误代码准确信息 和 源代码的错误位置
inline-source-map
:内联
只生产一个内联source-map
错误代码准确信息和源代码的错误位置
hidden-source-map
:外部
错误代码错误原因,但没有错误位置
不提供源代码位置,只提示构建后代码的错误位置
eval -source-map
:内联
每一个文件都生产对应的source-map文件,都在eval
错误代码准确信息和源代码的错误位置
nosources-source-map
:外部
错误代码准确信息,但不提供源代码信息
cheap-source-map
:外部
错误代码准确信息和源代码的错误位置
只能精确到行
cheap-module-source-map
:外部
错误代码准确信息和源代码的错误位置
module会将loader的source map加入
内联和外部的区别: 1.外部生产了文件,内联没有。 2.内联构建速度更快
开发环境: 速度快,调试友好
速度快(eval>inline>cheap>…)
eval-cheap-source-map
eval-source-map
调试友好
source-map
cheap-module-source-map
cheap-source-map
–> eval-source-map(性能更好) /eval-cheap-module-source-map(调试更好)
生产环境:源代码是否开放? 调试友好?
内联会让代码更大,排除,都是使用外部方式
cheap-source-map
1.5.3:babel缓存
类似于hmr,开启babel缓存后
cacheDirectory: true
1.5.4:文件资源缓存
使用hash值,将每次打包的js或者css附上哈希值(类似于版本号)可以避免缓存导致的页面未刷新
[hash:10]
[contenthash:10] 根据文件的内容生产hash值。不同文件hash值一定不一样
[chunkhash:10] 根据chunk生产的hash值。如果打包来源于同一个chunk,那么hash值就一样
1.5.5:tree-shaking
作用:去除无用代码
前提:1.必须使用es6模块化 2.开启production环境
作用:减少代码体积
在package.json中配置
"sideEffect":false 所有代码都没有副作用(都可以进行tree shaking)
可能会把css/@babel/polyfill文件干掉
"sideEffect":["*./css"] 除了css文件外的,其他文件的代码没有副作用(可以进行tree shaking)
1.5.6:code split
代码分割
//单页面
entry: './src/js/index.js'
//多入口 对应多个bundle
entry: {
main: './src/js/index.js',
test: './src/js/test.js'
}
output: {
//[name]对应文件名
filename: 'js/[name].[contenthash:10].js'
}
//可以将node_modules中代码单独打包一个chunk最终输出
//简单点来说,就是三方库单独打包,自己的代码也单独打包,可以防止多入口文件中重复引入三方库
optimization: {
splitChunks: {
chunks: 'all'
}
}
1.5.7:懒加载,预加载
用代码分割的方式,使用import的方式,将文件异步的引入到触发方法中,等方法触发,实现懒加载
正常加载,并行加载(同一时间加载多个文件)
1.5.8: PWA渐进式网络开放应用程序(离线可访问)
可以让应用离线后继续访问
workbox --> workbox-webpack-plugin
1.5.9: externals
防止其他资源打包到bundle文件中
externals: {
jquery: 'jQuery'
}
1.5.10: dll
将多个库打包成一个文件