基础
使用原因
1.受限于js文件加载顺序从上往下,可能导致加载失败
2.作用域问题,挂载在window上变量过多,可能导致冲突(可使用立即调用函数表达式IIFE创建独立作用域)
(function(){
var name = '123'
})()
console.log(name)
3.代码拆分,(依赖ES6实现)使用export default XX 来暴露模块,import XX form XX 来引入模块,
需要在script标签上添加 type="module" 属性
安装webpack
1.安装node
2.全局安装:npm i webpack webpack-cli --global(不建议,易产生版本不一致问题)
3.项目下安装:npm install webpack webpack-cli --save-dev
4.npm init -y生成package.json
5.webpack -v查看版本
运行webpack
1.全局:终端输入webpack,生成dist文件夹; webpack -status -datailed查看打包详情
2.当前目录:npx webpack;可在之后加上--help查看其他指令
配置webpack
在当前目录新建名为webpack.config.js的文件
const path=require('path')
module.exports={
entry:'/src/index.js' //定义入口文件
output:{ //打包文件
filename:'bundle.js',
path:path.resolve(__dirname,'./dist')
},
mode:'development',
devtool:'inline-source-map'
}
关于devtool:
1.7种SourceMap模式
2.webpack文档
插件
HtmlWebpackPlugin
安装:npm install html-webpack-plugin -D
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports={
entry:'./src/index.js',
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'./dist')
},
mode:'development',
devtool: 'inline-source-map' ,
plugins:[
new HtmlWebpackPlugin({
template:'./index.html', //参考的html
filename:'app.html', //生成文件名
inject:'body' //指定script语句插入到body中
})
],
}
webpack-dev-server
可以直接通过npx webpack --watch命令实现编译时自动检测文件变化,但需要手动刷新浏览器
使用插件使得文件打包后的本地代码实时更新,提高webpack开发效率
安装: npm install webpack-dev-server -D
配置:
module.exports={
...
devServer:{
static:'./dist' //server的根目录,物理路径
},
}
要先执行编译后再执行:npx webpack-dev-server --watch
或npx webpack serve或npx webpack-dev-server --open(直接在浏览器打开)
资源模块
module: {
rules: [
{
test: /\.png$/, //正则表达式
type: "asset/resource", //发送一个单独的文件并导出 URL
generator: {
filename: 'images/test.png' //第二种方法,会覆盖output中的名字设置
}
},
{
test: /\.svg$/,
type: 'asset/inline', //导出一个资源的 data URI
},
{
test: /\.txt$/,
type: 'asset.source', //导出资源的源代码
},
{
test: /\.jpg$/,
type: 'asset', //在导出一个 data URI 和发送一个单独的文件之间自动选择
parser: {
dataUrlCondition: {
maxSize: 4 * 1024 //默认值为4k,大于4k发送一个单独的文件,小于导出dataUrl
}
}
}
]
}
loader
cssloader
分别安装loader后修改配置:
module: {
rules: [
{
test: /\.(css|less)$/,
use: ['style-loader','css-loader','less-loader'] //从后往前链式解析
}
]
}
抽离与压缩css
抽离:执行npm install mini-css-extract-plugin安装插件(必须在webpack5环境下)
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "app.html",
inject: "body"
}),
new MiniCssExtractPlugin({
filename: "styles/[contenthash].css"
})
],
module: {
rules: [
{
test: /\.(css|less)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
}
]
}
压缩:
执行npm install css-minimizer-webpack-plugin安装插件
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
mode: "production", //需改为生产模式
optimization: {
minimizer: [
new CssMinimizerWebpackPlugin()
]
}
}
代码分离
项目中若存在多个入口文件时,则需要代码分离;若存在多个模块共用的代码时,也需要分离代码来防止重复打包。
入口起点:
entry:{
index:'./src/index.js',
another:'./src/another-module.js'
},
output:{
filename:'[name].bundle.js',
path:path.resolve(__dirname,'./dist'),
clean:true,
assetModuleFilename:'images/[contenthash][ext]',
},
问题:多入口文件会导致存在相同文件时,重复打包至各自模块
entry依赖:
Entry dependencies
例如当两个模块共有lodash时,会抽离出来并取名为lodash。
entry:{
index:{
import:'./src/index.js',
dependOn:'shared'
},
another:{
import:'./src/another-module.js',
dependOn:'shared'
},
shared:'lodash'
index:'./src/index.js',
another:'./src/another-module.js'
}
SplitChunksPlugin
配置时依旧可以采用独立命名
entry:{
index:'./src/index.js',
another:'./src/another-module.js'
}
在 optimization 优化配置项中添加 splitChunks
optimization:{
...
splitChunks:{
chunks:'all'
}
}
动态引入
通过import实现动态引入,且不影响其他模块抽离方式
假设async-module.js 为功能模块
function getComponent(){
return import('lodash').then(({default:_})=>{
const element = document.createElement('div')
element.innerHTML = _.join(['hello','webpack'],' ')
return element
})
}
getComponent().then((element)=>{
document.body.appendChild(element)
})
在其他文件中引入import './async-module.js'
懒加载
可以加快应用的初始载入速度,减轻总体积,没有使用到的模块先不加载,使用时再进行加载
button.addEventListener('click',()=>{
//加上注释 webpackChunkName:'模块名' 后,可以定义打包后的模块名
import(/* webpackChunkName:'math' */'./math.js').then(({add})=>{
console.log(add(4,5));
})
})
预获取/预加载模块
在声明import时,使用下面这些内置指令,可以让webpack输出“resource hint(资源提示)”,来告知浏览器:
prefetch(预获取):将来某些导航下可能需要的资源 ,即在浏览器网络空闲时再获取资源
preload(预加载):当前导航下可能需要资源,和懒加载效果类似
const button = document.createElement('button')
button.textContent = '点击执行加法运算'
button.addEventListener('click',()=>{
import(/* webpackChunkName:'math',webpackPrefetch:true*/'./math.js').then(({add})=>{
console.log(add(4,5));
})
})
document.body.appendChild(button)