一、简介
概述
本次使用webpack4进行构建打包
二、webpack
安装webpack、webpack-cli
npm install webpack@4.2.0 webpack-cli@4.2.0 -D
三、loader
加载器概述
-
raw-loader:加载文件原始内容(utf-8)
-
file-loader:把文件输出到一个文件夹中,在代码中通过相对URL去引用输出的文件
-
url-loader:和file-loader类似,但是能在文件很小的情况下以base64的方式把文件内容注入到代码中
-
source-map-loader:加载额外的Source Map文件,以方便断点调试
-
svg-inline-loader:将压缩后的 SVG 内容注入代码中
-
image-loader:加载并且压缩图片文件
-
handlebars-loader: 将 Handlebars 模版编译成函数并返回
-
babel-loader:把ES6转化成ES5
let----降级---->plugin
箭头函数----降级--->plugin
-
ts-loader: 将 TypeScript 转换成 JavaScript
-
awesome-typescript-loader:将 TypeScript 转换成 JavaScript,性能优于 ts-loader
-
css-loader:加载css,支持模块化、压缩、文件导入等特性,帮我们分析出各个css文件之间的关系,把各个css文件合并成一段css;
-
style-loader:把css代码注入到js中,通过DOM操作去加载css
-
eslint-loader:通过ESLint检查JS代码
-
tslint-loader:通过 TSLint检查 TypeScript 代码
-
postcss-loader:扩展 CSS 语法,使用下一代 CSS,可以配合 autoprefixer 插件自动补齐 CSS3 前缀
-
vue-loader:加载 Vue.js 单文件组件,它可以解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理
-
cache-loader: 可以在一些性能开销较大的 Loader 之前添加,目的是将结果缓存到磁盘里
1.安装sass加载器和模块
其实之所以用到node-sass、是因为sass-loader的缘故。sass-loader 是将sass文件编译成css,而sass-loader又依赖于node-sass,所以需要安装node-sass
npm install node-sass sass-loader -D
2.安装css加载器和安装style加载器
大概流程是,css loader将css包裹成js, 传给style loader 然后style loader再将它处理成一个立即执行函数封装到bundle中. 这个立即执行函数会生成一个style标签嵌入到HTML页面中
-
css-loader:加载css,支持模块化、压缩、文件导入等特性
-
style-loader:把css代码注入到js中,通过DOM操作去加载css
npm install css-loader style-loader -D
npm install style-loader -D
3.安装ts加载器
将 TypeScript 转换成 JavaScript
npm install ts-loader -D
4.安装vue加载器
它可以解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理
npm install vue-loader@15.10.1 -D
5.安装babel加载器
能够把es6高级内容变为es5,es6/es7/es8等等高级标准有很多(let、箭头函数、对象解构赋值、...展开运算符、反勾号字符串等等),每个标准都需要一个独立的plugin进行降级处理,如果使用许多高级标准内容,那么势必要为此安装许多plugin,这样工作比较繁琐,系统已经考虑到这点了,其通过preset把许多常用的plugin给做了集合,因此一般性的使用只需要安装preset即可搞定(如果项目应用到了一个生僻的高级标准内容,preset处理不来,就还需要再安装对应的plugin处理)
npm i babel-loader @babel/core @babel/preset-env -D
{
test: /.js$/,
exclude: /node_modules/, // 排除目录
use: [
{
loader:'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
] // es6转es5
}
说明: @babel/preset-env用来指定按什么样的预设来进行降级处理
- 打包测试 打包之后,去打包后的文件中检查是否已经把const和箭头函数这种es6的代码转成了es5的代码。
6.PostCSS
-
PostCSS是一个通过JavaScript来转成样式的工具
-
这个工具可以帮助我们进行一些css的转化和适配,比如自动添加浏览前缀,css样式的重置
PostCSS内部也是通过各种插件来实现转化的,所以需要安装各种插件来使用
npm install postcss-loader -D
npm install autoprefixer -D //需要安装插件,添加浏览器前缀的
module: {
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader', {
loader: 'postcss-loader',
options: {
//可以提出一个单独的文件
postcssOptions: {
plugins: [
require('autoprefixer')
]
}
}
}]
}
]
}
当使用postcss-loader的时候,会先查找有不有自己options选项,如果没有就去查找postcss.config.js
这个配置文件
postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
webpack.config.js
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader']
}
postcss-preset-env
一个比较强大的postcss插件
它可以帮助我们将一些现代的CSS特性,转成大多数浏览器认识的CSS,并且会根据目标浏览器或者运行时环境 添加所需的polyfill;
也包括会自动帮助我们添加autoprefixer(所以相当于已经内置了autoprefixer)
安装:
npm install postcss-preset-env -D
使用:
跟autoprefixer使用是一样的,可以直接用postcss-preset-env
替换autoprefixer
效果也是一样的
7. file-loader
file-loader的作用就是帮助我们处理import / require()方式引入的一个文件资源,并且会将它放到我们输出的文件夹中
在使用图片有两种形式,一种是背景图片
,另外一种是img标签
//简单创建一个img标签
import image from '../imgs/mode.png'
const el = document.createElement('img')
el.src = image
document.body.appendChild(el)
注意:当使用img标签的时候,我们把图片看成是一个模块
,不要直接写成是一个字符串
安装
npm install file-loader -D
使用
//webpack.config.js
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader'
}
]
}
]
}
上面的配置,可以直接展示出图片来了,也就说明加载成功了。
但是还是存在一种不是很友好的现象
打包过后的文件,就直接存在build文件夹中,如果是一张图片还好,如果有很多张图片,就会造成打包文件夹的结构混乱
。图片被打包的文件名是32位hash值
,我们不能分辨
哪张是对应的哪张图片。所以需要进行处理。
所以需要对file-loader进行options
配置
常见的配置:
[ext] 处理文件的扩展名
[name] 处理文件的名字
[hash:] 截取hash的长度,默认的32个字符太长了
[path] 文件相对于webpack配置文件的路径
//重新对file-loader进行配置
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
//在打包的文件夹中创建一个images文件夹,用来保存图片的
outputPath: 'images',
//给图片取名字
name: "[name]_[hash:8].[ext]"
}
}
]
}
]
}
效果图:
8.url-loader
url-loader跟file-loader的工作原理是一样的
url-loader的区别: 就是对图片有限制,对图片较小的进行base64编码
所以会发现,打包过后的文件,就一个build.js,而且里面都还是base64
这也不是我们想要的,只对限制一下的图片,进行base64的转换。
为什么呢?
小的图片转换base64之后可以和页面一起被请求,减少不必要的请求过程
而大的图片也进行转换,反而会影响页面的请求速度
小于100kb
的图片,进行转化
{
test: /\.(jpe?g|png|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: {
//在打包的文件夹中创建一个images文件夹,用来保存图片的
outputPath: 'images',
//给图片取名字
name: "[name]_[hash:8].[ext]",
//配置limit
limit: 100 * 1024
}
}
]
}
9.加载数据(CSV/TSV/XML)
除了js,json,images, 可以加载的有用数据还有CSV/TSV/XML,要导入CSV, TSV和XML,可以
使用csv-loader和xml-loader
安装插件:
npm i csv-loader xml-loader -D
module.exports = {
...
module: {
rules: [
{
test: /\.(csv|tsv)$/,
use: 'csv-loader'
},
{
test: /\.xml$/,
use: 'xml-loader'
}
]
}
}
四、插件(Plugin)
1.webpack-dev-server
项目开发都是对src目录内部的文件进行更新,不要去修改dist打包好的文件,现在对src内部的任何文件做修改操作后,都需要重新打包,才可以看到对应效果
npm i webpack-dev-server -D
在webpack.config.js中做如下配置
module.exports = {
// 其他省略....
// 配置 webpack-dev-server的选项
devServer: {
host: '127.0.0.1', // 配置启动ip地址
port: 10088, // 配置端口
open: true // 配置是否自动打开浏览器
}
}
在package.json中补充一个script
"scripts": {
+ "dev": "webpack-dev-server",
// 它默认会找webpack.config.js文件
"build": "webpack-dev-server --config webpack.config.js"
// 指定使用webpack.config.js配置文件文件
},
-
启动命令 现在通过
npm run dev
就可以实现 实时打包、实时编译、实时浏览器查看效果了。它会自动打开一个浏览器窗口。 -
测试
-
-
修改.js代码,
-
修改.css代码,检查是否会重启
-
2.HtmlWebpackPlugin
npm i html-webpack-plugin -D
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
plugins:[
new HtmlWebpackPlugin({//设置模板文件
template:'./src/index.html',//使用打包后的模板文件
filename:'index.html'//打包后文件的名字
}) ,
]
}
上述的这个如果需要在index中假如一些自动以的内容是根据development与production不同,而添加不同的内容。在这里html-webpack-plugin插件已经帮助我们做好了这部分。在你需要打包是自动需要假如的内容 使用
<%= htmlWebpackPlugin.options.urlScript %>
要说明的是urlScript 这个是我们自己定义的,你可以叫任何的名字,在传入的时候使用这个变量放入插件的内置中
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
plugins:[
new HtmlWebpackPlugin({//设置模板文件
template:'./src/index.html',//使用打包后的模板文件
filename:'index.html'//打包后文件的名字
urlScript:'<script src="./js/zepto.min.js"></script> '//---<<---就这里
}) ,
]
}
未经过html转换的文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title>
<head>
<body>
</body>
<%= htmlWebpackPlugin.options.urlScript %>
</html>
经过 html-webpack-plugin 的转换之后就会变成
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title></title>
<head>
<body>
</body>
<script src="./js/zepto.min.js"></script> -->>之前的标间就被替换成为了 我们之前的插件设置的内容了,这个很有用
</html>
3.VueLoaderPlugin
作用是 对本次webpack编译的所有rules做操作,添加pitch-loader和vue-loader,进行一个顺序的重新排放,
最终rule中的顺序是这样的: [ pitch-loader, ... ... , vue-loader] (pitcher在在开始,vue-loader在最后,这一切是通过把...clonedrule放到中间来实现的)
( * pitchloader的resourceQuery函数表明了,这个loader只会对request中带有vue字段query的request使用pitchloader)
4. process
npm i --save-dev process
5.抽离css为单独的文件
安装抽离css为单独文件的插件:该插件基于webpack5构成,主要是把style标签引入css转化为link
引入css
安装插件:
npm i mini-css-extract-plugin -D
配置:
// 引入抽离css为独立文件的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
...
plugins: [
new MiniCssExtractPlugin({
// 指定抽离的之后形成的文件名
filename: 'styles/[contenthash].css'
})
],
module: {
rules: [
// 处理后缀名为.css或者是.less的文件
{
test: /\.(css|less)$/,
// stuyle-loader作用是在 head 中创建 style 标签
// MiniCssExtractPlugin.loader是将css抽离为独立的文件
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
}
]
}
}
五、CSS优化(压缩)
安装插件:
npm i css-minimizer-webpack-plugin -D
配置:
/ 引入css压缩插件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
module.exports = {
...
// 优化配置项
optimization: {
minimizer: [
// 使用插件优化 css 代码
new CssMinimizerPlugin()
],
},
// 模式,因为压缩css代码只在生产模式下生效
mode: 'production'
}
六、字体资源
通过 CSS 引入字体资源
@font-face {
font-family: 'PujiSansExpandedHeavy';
src: url('../fonts/PujiSans-ExpandedHeavy.eot'); /* IE9 Compat Modes */
src: url('../fonts/PujiSans-ExpandedHeavy.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/PujiSans-ExpandedHeavy.woff2') format('woff2'), /* Modern Browsers */
url('../fonts/PujiSans-ExpandedHeavy.woff') format('woff'), /* Modern Browsers */
url('../fonts/PujiSans-ExpandedHeavy.ttf') format('truetype'); /* Safari, Android, iOS */
font-style: normal;
font-weight: normal;
text-rendering: optimizeLegibility;
}
配置:
module.exports = {
...
module: {
rules: [
// 配置字体文件
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
// asset/resource可以帮助我们载入任何类型
type: 'asset/resource'
}
]
}
}
Node API 方式
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 访问内置的插件
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
},
],
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({ template: './src/index.html' }),
],
};
在使用 Node API 时,还可以通过配置中的 plugins
属性传入插件。
some-node-script.js
const webpack = require('webpack'); // 访问 webpack 运行时(runtime)
const configuration = require('./webpack.config.js');
let compiler = webpack(configuration);
new webpack.ProgressPlugin().apply(compiler);
compiler.run(function (err, stats) {
// ...
});
webpack打包成的dist启动运行
安装express-generator生成器
npm install express-generator -g
创建一个express项目 执行express expressDemo
(expressDemo是项目名)
expressDemo项目目录如下图:
进入expressDemo目录,安装项目依赖 执行npm install
把dist目录下的所有文件复制到express项目的public文件夹下
运行npm start
启动expressDemo项目,打开浏览器,输入http://localhost:3000即可访问。