本质上,webpack
是一个现代 JavaScript
应用程序的静态模块打包器(module bundler
)。当 webpack
处理应用程序时,它会递归地构建一个依赖关系图(dependency graph
),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
。
前提:需要node.js环境(安装配置node.js环境)
本地安装webpack命令如下:
npm install webpack webpack-cli -D
// a.js
module.exports = 'hello'
// index.js
let str = require('./a.js')
console.log(str)
文件webpack.config.js
是webpack的配置文件,
webpack是node写出来的,因此用node的写法
// webpack.config.js 内容
let path = require('path')
module.exports = {
mode:'development', // 模式 默认两种:production development
entry:'./src/index.js', // 入口
output:{
filename:'bundle.js', // 打包后的文件名
path: path.resolve(__dirname, 'dist'), // 路径必须是一个绝对路径
}
}
上面基础配置含义为:
在开发模式下(文件不压缩),根据入口文件./src/index.js
的内容,构建内部依赖图并处理,最后输出到出口文件当前目录下的dist文件中的文件名为bundle.js的文件上
mode
属性设置webpack的模式
production
生产模式,打包后的代码是压缩的development
开发模式, 打包后的代码是不压缩的相关属性:
entry
设置打包入口
output
属性设置的文件中output
设置打包出口
如果你不想使用webpack默认配置文件名webpack.config.js
,而是想使用myConfig.js
这样的文件名
只需要在执行webpack时,在命令后面追加文件名即可
例如:
默认文件名执行命令
npx webpack
设置文件名执行命令
npx webpack --config myConfig.js
一般情况下,我们可以在package.json
里写一些脚本来处理如上情况:
"scripts": {
"build": "webpack --config myConfig.js"
},
这个时候只需在命令行里输入npm run build
命令,即可执行webpack --config myConfig.js
前面我们用webpack打包生成了bundle.js文件;要执行该文件,我们可以在dist文件下创建index.html
在里面用script
导入bundle.js
文件
<body>
<script src="bundle.js"></script>
</body>
右键打开浏览器,即可执行该页面
如果我们想要开启服务,地址为localhost
这样来访问,要如何设置?
安装webpack-dev-server
npm i webpack-dev-server -D
配置webpack.config.js
devServer:{ // 开发服务器的配置
port:3000, // 修改端口号
progress:true,
contentBase:'./dist'
},
如果dist
文件里没有html文件,需要我们生成到dist
文件下,该如何做?
首先,src
源代码文件下有个模板文件index.html
安装html-webpack-plugin
插件
npm i html-webpack-plugin -D
在webpack.config.js
里配置:
plugins:[ // 数组 放置所有的webpack插件
new HtmlWebpackPlugin({
template:'./src/index.html',
filename:'index.html',
minify:{
removeAttributeQuotes:true, // 删除文件里的双引号
collapseWhitespace:true, // 文件压缩为一行
},
hash:true // 生成hash戳,会在script引入的文件名后追加hash值
})
]
执行npm run build
后,就会在dist
文件里生成bundle.js
和index.html
给文件名生成hash值,防止缓存
webpack.config.js
里设置:
output:{
filename:'bundle.[hash].js',
path:path.resolve(__dirname,'dist')
},
output:{
filename:'bundle.[hash:8].js',
path:path.resolve(__dirname,'dist')
},
安装css-loader
和style-loader
npm i css-loader style-loader -D
webpack.config.js
里配置
module:{ // 模块
rules:[ // 规则
// css-loader 解析 @import这种语法
// style-loader 把css插入到head的标签中
// loader的特点,希望单一
// loader的用法,一个loader 用字符串
// 多个loader 用[]
// loader的顺序,默认从右向左执行(从下到上)
// loader还可以写成对象,好处是里面还可以传参数
{
test: /\.css$/,
use:[
{
loader: 'style-loader',
},
'css-loader'
]
},
]
}
如果要处理less
文件
首先安装:
npm i less less-loader -D
webpack.config.js
->module
->rules
里配置:
{
test: /\.less$/,
use:[
{
loader: 'style-loader',
},
'css-loader',
'less-loader' // 把less 转成css
]
},
其他文件sass
stylus
配置类似
上面是把样式放到style
标签里,那么如何用link
标签来引入样式呢?
首先安装插件:
npm i mini-css-extract-plugin -D
webpack.config.js
里配置:
引入mini-css-extract-plugin
let MiniCssExtractPlugin = require('mini-css-extract-plugin')
plugins
里配置
new MiniCssExtractPlugin({
filename:'main.css' // 抽离出的文件名
})
module
里配置:
module:{ // 模块
rules:[ // 规则
{
test: /\.css$/,
use:[
MiniCssExtractPlugin.loader,// css文件用link引入
'css-loader'
]
},
{
test: /\.less$/,
use:[
{
loader: 'style-loader',
},
'css-loader',
'less-loader' // 把less 转成css
]
},
]
}
为了浏览器兼容,我们需要给一些css属性加上前缀,例如-webkit-
安装:
npm i postcss-loader autoprefixer -D
webpack.config.js
里配置:
module:{ // 模块
rules:[ // 规则
{
test: /\.css$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader', // 添加前缀
]
},
{
test: /\.less$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'less-loader' // 把less 转成css
]
},
]
}
module.exports = {
plugins : [
require('autoprefixer')({
overrideBrowserslist: [
"Android 4.1",
"iOS 7.1",
"Chrome > 31",
"ff > 31",
"ie >= 8"
//'last 10 versions', // 所有主流浏览器最近10版本用
],
grid: true
})
]
}
如上配置好后,运行代码,CSS属性就会自动加上前缀了。
CSS压缩打包
安装插件optimize-css-assets-webpack-plugin
,因为使用了这个插件,css虽然压缩了,可js却变为不压缩了。因此还需要安装插件terser-webpack-plugin
npm i optimize-css-assets-webpack-plugin terser-webpack-plugin -D
webpack.config.js
里配置:
导入插件:
let TerserJSPlugin = require('terser-webpack-plugin')
let OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
配置:
optimization: { // 优化项
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
这样子,打包出来的js和css都为压缩格式了。
浏览器对一些高级语法的支持性并不是非常好,因此我们需要使用Babel来做一些转化
支持例如:let fn = () => {}
es6的箭头函数语法
安装:
npm i babel-loader @babel/core @babel/preset-env -D
支持例如:
es7语法
class People{
constructor(name){
this.name = name
}
}
安装:
npm i @babel/plugin-proposal-class-properties -D
webpack.config.js
->module
->rules
里配置:
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/ // 排除node_modules中的文件
},
根目录下创建.babelrc
文件:
// .babelrc
{
"presets": ["@babel/preset-env"],
"plugins":[
"@babel/plugin-proposal-class-properties"
]
}
如果想使用装饰器例如@log
,配置如下:
安装:
npm install --save-dev @babel/plugin-proposal-decorators
.babelrc
里配置:
{
"presets": ["@babel/preset-env"],
"plugins":[
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
}
如果要使用generators
, async
等函数,需要安装:
开发依赖
npm install --save-dev @babel/plugin-transform-runtime
生产依赖
npm install --save @babel/runtime
.babelrc
里配置:
{
"presets": ["@babel/preset-env"],
"plugins":[
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }],
["@babel/plugin-transform-runtime"] // 添加
]
}
如果要使用更高级的语法例如'abc'.includes('a')
babel只会转换E6语法,而不会转换新的api,让新的api生效的方法是使用传统的polyfill,为此需要引入这个模块
安装:
npm i @babel/polyfill
使用:
require('@babel/polyfill')
'abc'.includes('a')
JS校验怎么弄?
安装:
npm i eslint eslint-loader
webpack.config.js
->module
->rules
里配置:
因为loader
默认 从右向左/从下到上 执行,校验肯定要在最前面的,因此需要加个enforce
属性
{
test:/\.js$/,
use:{
loader:'eslint-loader',
options:{
enforce:'pre' // previous 强制先执行
}
}
},
另外还需要.eslintrc.json
文件,里面是一些校验规则
你可以在eslint
官网上进行校验规则勾选,然后下载文件,把它放入项目根目录中:
注意,文件名为.eslintrc.json
,前面有个点;
最后,运行代码,就能检查出你的语法是否规范;