英文文档:webpack.js.org/
中文文档:webpack.docschina.org/concepts/
一、webpack相关概念
-
什么是webpack
-
Webpack是一个模块打包器——构建工具
- 浏览器只认识html、js、css;其他的像less,是不认识的,所以需要构建工具处理成浏览器认识的文件
-
在Webpack看来, 前端的所有资源文件(js、json、css、im、less...)都会作为模块处理
-
它将根据模块的依赖关系进行静态分析,生成对应的静态资源
-
-
核心内容
-
默认配置文件
- webpack.config.js : 是一个node模块,返回一个 json 格式的配置信息对象
-
entry:入口文件,指示 webpack 从哪个文件开始来作为构建其内部依赖图的开始;可以是字符串也可以是数组或者对象
-
output:指示webpack将打包好的文件输出到哪个文件以及如何命名
-
loader:loader 让 webpack 能够去处理那些非 JavaScript 、json文件
-
webpack 自身只能解析: JavaScript、json,可以解析部分es6语法,比如es6的模块化,但是像promise等语法是不能解析的
-
webpack官方出品,所以比较规范,一般以 xxx-loader 的方式命名,xxx 代表了这个 loader 要做的转换功能
-
Loader 本身也是运行在 node.js 环境中的 JavaScript 模块(可以自己使用node.js开发loader)
-
它本身是一个函数,接受源文件作为参数,返回转换的结果
-
-
plugins:插件则可以用于执行范围更广的任务,如压缩、优化等
-
Plugins来自很多优秀程序员,所以命名不是那么规范
-
CleanWebpackPlugin: 自动清除指定文件夹资源
-
HtmlWebpackPlugin: 自动生成HTML文件并
-
UglifyJSPlugin: 压缩js文件
-
.....
-
-
mode:模式,用于指定开发环境还是生产环境
-
development——开发环境
-
production——生产环境
-
生产环境会压缩代码
-
-
二、webpack的基本使用
-
源代码一般放到src,打包之后的代码一般放到dist或者build
- 源码里面一般有这几个文件夹js、html、json、imgaes等
-
webpack基于node(node必须10以上)
-
先让我们的代码变成一个包管理项目
- npm init
-
安装webpack和webpack-cli
-
需要全局安装和局部安装
-
npm i webpack webpack-cli -g
-
npm i webpack webpack-cli -D
-
-
可以使用webpack进行工作了
-
使用es6的模块化暴露和引入文件(es6的模块化浏览器是不认识的)
-
使用命令webpack src/js/index.js -o dist/index.js --mode=development
-
将src下的js下的index.js打包输出为dist文件夹下的index.js
-
-
webpack的基本功能是可以编译和打包js和json文件,能够将es6的模块语法转化成浏览器可以识别的语法,能压缩代码(在production模式下自动压缩)
三、使用webpack配置文件
-
每次输入一长串命令很麻烦
-
执行webpack命令时,会在当前目录查找webpack.config.js文件读取配置
-
通过Commonjs暴露出去一个对象,里面可以配制参数,一般有以下几个参数
-
entry:入口文件,将所有打包资源全部引入
-
output:输出,将资源输出到指定目录下
-
loader:处理webpack不能够解析的模块
-
plugins:执行loader做不了的任务
-
mode:打包模式
-
-
可以在package.json里面指定短命令
-
在script对象中用key值代替val值中要执行的命令,使用时用npm run key值
-
四、使用loader解析less文件(使用less-loader)
-
在使用less-loader的时候必须要less、css-loader、style-loader
- less-loader是将less转换成css
- css-loader是将css以CommonJs语法打包到js中
- style-loader创建一个style标签,将js中的css放入其中
-
安装less-loader、css-loader
五、js语法检查(eslint eslint-loader)
-
安装eslint eslint-loader
- npm i eslint eslint-loader -D
-
配置loader
- eslint规则有两种方式
- 配置loader的options规则里面(还在报错,待解决....)
- 使用formatter引入外部资源
- 外部资源为当前路径下.eslintrc命名的文件
- 配置到package.json中
- loader配置中的options选项不写
- 在package.json中追加配置eslintConfig
- 配置loader的options规则里面(还在报错,待解决....)
- eslint规则有两种方式
"eslintConfig": {
"parserOptions": {
"ecmaVersion": 6,//支持es6语法
"sourceType": "module" //支持模块化引入
},
"env": {// 支持的运行环境
"browser": true, // 浏览器环境
"node": true //node环境
},
"globals": {//可以使用的全局变量
"$": "readonly",
"Promise": "readonly"
},
"rules": {// 一些自定义规则
"no-console": 0,
"eqeqeq": 2,
"no-alert": 2
},
// 扩展,值为 "eslint:recommended" 的 extends 属性启用一系列核心规则
"extends": "eslint:recommended"
}
{
text:/.js$/,
exclude: /node_modules/, //排除node_modules文件夹
enforce: "pre", //提前加载使用
use: ['eslint-loader'],
// 可以在这里配置eslint的规则,但是一般不在这里配置,
// 可以配置在package.json中,也可以使用单独的文件配置
options: {
formatter: require('eslint-friendly-formatter')
}
}
六、js语法转换和兼容性处理
- 使用babel将es6转换为es5
-
安装babel-loader
-
npm install babel-loader @babel/core @babel/preset-env -D
-
{
test:/.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
-
缺点
-
只能转换简单的es6语法,如let、const、箭头函数
-
不能转换promise等
-
-
转换更多的es6语法
-
使用babel-polyfill
- 包含ES6的高级语法的转换,不管编码人员用了哪些新语法,全部的新语法都转换
- 安装:npm i babel-polyfill -D
- 在入口文件直接引入就可以
- import 'babel-polyfill'
- 还没有写啥呢打包完就四百多KB
-
使用core-js
- 按需转换,使用了啥转换啥
- 安装core-js
- npm i core-js -D
- 在bable-loader的基础上追加配置
-
{
test:/.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage', // 按需引入需要使用polyfill
corejs: { version: 3 }, // 解决不能够找到core-js的问题
targets: { // 指定兼容性处理哪些浏览器
"chrome": "58",
"ie": "9"
}
}
]
]
}
}
}
七、url-loader处理图片资源&base64
- 使用url-loader就不使用file-loader
- 安装:npm install url-loader -D
-
配置:
{
test: /.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader', //不做图片转base64,可以用file-loader
options: {
limit: 8192,
outputPath:'img', //图片最终输出的位置
publicPath:'../build/img',//css资源图片路径
name:'[hash:5].[ext]' //修改图片名称
}
}
]
}
八、html文件的处理(生成html文件)
- 想让webpack自动的帮我们创建一个html
- 然后把我们想要引入的东西引入进来,所以要借助插件
- 安装插件:
- npm i html-webpack-plugin -D
- 引入插件:const HtmlWebpackPlugin = require('html-webpack-plugin');
-
使用插件:
new HtmlWebpackPlugin({
template: './src/index.html', // 以当前文件为模板创建新的HtML
minify: {
removeComments: true, //移除注释
collapseWhitespace: true, //折叠所有留百
removeRedundantAttributes: true, //移除无用的标签
useShortDoctype: true,//使用短的文档声明
removeEmptyAttributes: true,//移除空标签
removeStyleLinkTypeAttributes: true,//移除rel="stylesheet"
keepClosingSlash: true,//自结束
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
}
})
九、使用html-loader处理html文件中的外部资源
- 在html中引入图片或者其他资源,打包之后引用地址不对
- 安装:html-loader
-
使用:
{
test: /.(html)$/,
use: {
loader: 'html-loader'
}
}
- 在这里要特别注意,到目前为止如果打包,那么html中的img的src依然是不正确的
-
需要在url-loader中追加参数esModule:false
{
test: /.(png|jpg|gif)$/i,
loader: 'url-loader', //如果不做图片转base64,可以用file-loader
options: {
limit: 8192, // 小于这么多M的自己转base64
outputPath:'images', //图片最终输出的位置
publicPath:'./images/', //css资源图片路径
name:'[hash:4].[ext]', //修改图片名称
esModule:false
}
}
十、file-loader处理其他资源,如字体图标
- 安装:npm install file-loader --save-dev
-
配置
{
test: /.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/, // 处理其他资源
loader: 'file-loader',
options: {
outputPath: 'media',
name: '[hash:5].[ext]'
}
}
十一、使用插件提取css,合并为单独的文件
- 安装MiniCssExtractPlugin插件:npm i mini-css-extract-plugin -D
-
使用插件
new MiniCssExtractPlugin({
filename: "css/[name].css" //指定生成文件的目录和名字
})
-
在less-loader中不需要创建style标签
{
test:/.less$/,
// use数组中loader执行顺序:从右到左,从下到上 依次执行
use:[
MiniCssExtractPlugin.loader, //单独提取出一个css文件
// 'style-loader',// 创建style标签,添加上js中的css代码
'css-loader',// 将css以commonjs方式整合到js文件中
'less-loader'// 将less文件解析成css
]
}
十二、拆分prod配置文件和dev配置文件
- 当前目录下新建config文件夹
- 移动webpack.config.js文件到config中,改名为:webpack.prod.js
-
通过执行:webpack --display-modules --config ./config/webpack.prod.js 指定配置文件运行
- 这里需要将output配置路径修改为
prinft()
path:resolve(__dirname,'../dist')
-
命令太长,我们可以在package.json里面的script配置短命令
"start": "webpack-dev-server --config ./config/webpack.dev.js",
"build": "webpack --config ./config/webpack.prod.js"
-
webpack.dev.js同理
十三、在开发环境中配置自动化编译
-
安装dev-server:npm i webpack-dev-server -D
//配置自动化编译
devServer: {
open: true, // 自动打开浏览器
compress: true, // 启动gzip压缩
port: 3000, // 端口号
hot:true //开启热模替换功能 HMR
}
- 当前的自动化更新不能及时更新html和css
-
在入口文件配置中增加一个html的入口文件将会监听到html的变化
entry:['./src/js/index.js','./src/index.html']
- css文件打包引入使用的是插件,所以监听不了,需要改用loader
要配置一个完美的生态环境还远远不够........