持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情
前言
webpack 它可以打包 JavaScript 应用程序,支持 ES 模块化标准和 commonJS,可以扩展支持图片、字体文件、样式文件等静态资源打包;
构建工具对比
1、Webpack:适合一些复杂的应用,可以集成很多第三方库,可以拆分代码,使用静态资源文件,支持 commonJS、esmodule 等模块化模式;
2、Parcel:零配置,用户无需做其他的配置,开箱即用;适合简单的应用,并且可以快速的运行起来;
3、Rollup:用标准化的格式来编写代码(ES6)通过减少无用的代码来缩小包的体积;一般只能用来打包 JavaScript;适合一些类库并且只需要引入很少的第三方库;(Vue,React 框架)
4、Vite:基于 esmodule 构建,可以按需编译,热模块更新;可以和 Vue3 完美结合;
webpack使用
npm install webpack -d 当前项目安装
webpack-dev-server 提供了一个基本的 web server 并且具有实时重新加载的功能;
npx webpack --watch 在初次编译的时候在命令行后面加一个 watch,这也内容修改后控制台就会自动编译了;
webpack ./src/index.js ./dist/bundle.js
- 如果每次我们使用webpack的命令都要指定项目的源文件路径和打包后路径,就比较繁琐。我们是否可以将源文件路径和目标路径配置到文件中,每次运行时候读取文件的配置那?
- 当然可以,就是创建一个webpack.config.js文件
const path=require('path')//导入node.js中操作路径的模块
module.exports= {
entry:'./src/index.js',
output:{
path:'./dist',
filename:'bundle.js'
}
}
如果没有安装cli,会提示
npm install webpack-cli -g全局安装
执行webpack 报错
npx webpack局部安装执行
- configuration.output.path: The provided value "./dist/" is not an absolute path!
因此要配上绝对路径,利用node的 path库,
__dirname:表示当前文件的绝对路径
const path=require('path')//导入node.js中操作路径的模块
module.exports= {
entry:path.join(__dirname, './src/index.js'),//打包入口文件路径,
output:{
path: path.join(__dirname, './dist'),//输出文件的存放路径
filename:'bundle.js'
}
}
可以看到没有配置mode,指明环境,所以得在配置中在增加 mode:'production',然后在执行webpack,如下打印正常
打包之后的 bundle.js 在 html 文件中通过标签引入就可以正常使用了,但是我们想生成一个html自动引入这个js,该怎么办呢?
npm install --save-dev html-webpack-plugin
const path=require('path')//导入node.js中操作路径的模块
const HtmlWebpackPlugin = require('html-webpack-plugin');
//__dirname:表示当前文件的绝对路径
module.exports= {
mode:'production',
entry:path.join(__dirname, './src/index.js'),//打包入口文件路径,
output:{
//path.resolve(__dirname,'./dist'),//打包后文件放置的位置
path: path.join(__dirname, './dist'),//输出文件的存放路径
filename:'bundle.js',
clean:true //每次打包前清空dist文件夹
},
plugins:[
new HtmlWebpackPlugin({
template:'./index.html',// 模板,根据指定模板生成新的html
filename:'app.html',//生成文件的名称
inject:'body'//指定script标签位置
})
]
}
启动一个webpack server,
devServer:{
open: true,
port:8080,
static:"./dist/",//配置服务的跟目录,会自动打开项目下的html页面
// hot: true
}
项目下的index.html内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1>webpack</h1>
<h1>webpack</h1>
<h1>webpack</h1>
<h1>webpack</h1>
</div>
</body>
</html>
打包后通过webpack server运行
打包css
这里需要安装
//将css识别转化,让webpack可识别
npm install css-loader -d
//把css放置到页面 header 标签里面
npm install style-loader -d
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
}
这里要注意的是loader多个一起用,为什么要从右到左
loader 执行顺序从 use 数组的后面往前面执行,先执行的 loader 会将结果返回传递给下一个 loader;并且这个先后执行顺序必须正确,否则不生效;这里这样是因为需要先转化 css ,然后将 css 放到页面style上面;
使用方式
在我们对应的src跟目录下面创建一个存放css的文件夹,然后在需要打包的js中引入css,
如 import cs from './static/css/index.css'
重新执行打包,便可以在对应页面文件中使用这个样式文件
打包图片
配置fielLoader
{
test: /\.(png|svg|gif|jpe?g)$/,
use: {
loader: "file-loader",
options: {
outputPath: "img",
name: '[name]_[hash:6].[ext]',
},
},
type: 'javascript/auto'
}
注意的是: type: 'javascript/auto' 如果没有配置这个属性,那么打包的background-image图片只会显示在对应的dist目录下,不会输出到自定义的img目录。
踩坑:
因为file-loader@6.0.0版本中,为了优化性能新增了一个关键的配置项esModule 。这个配置项的作用,是指定引入文件的方式,是否指定es module的形式引入(也就是 improt name from ‘url’)这个配置项默认值是true,
如果是true的情况下,那再使用require或者<img src="./test.png">引用方式就会出现图片引用变为[Object,module]的形式,
解决办法 将 esModule设置为 false。在 file-loader 或 url-loader 内设置进去即可成功访问图片。
缓存第三方库
//缓存第三方库
optimization:{
splitChunks:{
cacheGroups:{
vendor:{
test:/[\\/]node_modules[\\/]/,
name:'vendors',
chunks:'all'
}
}
}
},
一些第三方库,很少像本地源代码那样频繁更改,因此可以使用缓存,在打包时配置上述代码,会把node_modules下的第三方包打包出来,命名为vendors的文件,
这个vendors.js的文件打包完成后,后续打包如果没有对第三方库的修改都不会变化的,根据浏览器的缓存机制,就能达到一定的缓存效果了。
总结
本文是自己练习webpack从0到1进行配置,基本总结了webpack的基础使用,还有很多其他的plugins、loaders可以配置,一个个配置过后加深理解。