近期看了webpack4.0的教程,以下是视频学习整理,供大家参考
视频地址:https://www.bilibili.com/video/av41546218
视频中的笔记见:https://malun666.github.io/aicoder_vip_doc/#/pages/vip_2webpack
webpack中文文档:https://www.webpackjs.com/
我根据视频教程的学习,截止到第15个视频,实践的代码及配置详见:
https://github.com/Niccce/webpackLearning/blob/master/webpackdemo/webpack4.x%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8.md
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
对比 Node.js 模块,webpack 模块能够以各种方式表达它们的依赖关系,几个例子如下:
import
语句require()
语句define
和 require
语句@import
语句。url(...)
)或 HTML 文件(
)中的图片链接(image url)webpack最好安装在项目中,若全局安装,就都是全局安装的版本,但是有一些老项目可能是用老版本的webpack开发的。
webpack官方文档写到:不推荐全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。
npm init -y
,初始化package.json文件npm i -D webpack
本地安装webpacknpm i -D webpack-cli
安装webpack-clinpm i lodash -P
安装lodashimport _ from 'lodash';
function createDomELement() {
let dom = document.createElement('div');
//使用了loadsh 的 join() 方法,将 字符串 用 空格进行 拼接
dom.innerHTML = _.join(['你好', 'webpack'], '');
return dom;
}
document.body.appendChild(createDomELement());
const path = require('path'); //引用path模块
//对外导出一个对象
module.exports = {
entry: './src/index.js', //入口
mode: 'development', //代表我们现在是开发阶段
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname,'dist')//最终main.js在哪个文件夹下
}
}
npx webpack
进行打包,dist中出现了main.js文件
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Documenttitle>
head>
<body>
<script src="./main.js">script>
body>
html>
在src中新建style文件夹及其中的index.css文件
.box{
color: yellow;
}
将样式给指定元素,修改index.js
import _ from 'lodash';
import './style/index.css';
function createDomELement() {
let dom = document.createElement('div');
//使用了loadsh 的 join() 方法,将 字符串 用 空格进行 拼接
dom.innerHTML = _.join(['你好', 'webpack'], '');
// dom.className = 'box';
dom.classList.add('box');
return dom;
}
document.body.appendChild(createDomELement());
安装:npm i -D style-loader css-loader
修改webpack.config.js
const path = require('path'); //引用path模块
//对外导出一个对象
module.exports = {
entry: './src/index.js', //入口
mode: 'development', //代表我们现在是开发阶段
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname,'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.css$/,//当引入的模块的后缀满足这个,就使用use的loader处理
use: ['style-loader', 'css-loader'] //处理顺序从右向左
}
]
}
}
执行npx webpack
查看效果
npm run build
代替npx webpack
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx webpack"
}
https://www.webpackjs.com/configuration/module/#rule-test
安装npm i -D sass-loader node-sass
此处可能会有遇到node-sass安装失败的问题,详见:https://blog.csdn.net/qq_41445033/article/details/100032529
修改webpack.config.js
const path = require('path'); //引用path模块
//对外导出一个对象
module.exports = {
entry: './src/index.js', //入口
mode: 'development', //代表我们现在是开发阶段
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname,'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: ['style-loader', 'css-loader','sass-loader']
//处理顺序从右向左
}
]
}
}
$bgcolor:red;
.box{
background-color: $bgcolor;
font-size: 30px;
}
import './style/a.scss'
npx webpack
查看效果
方法:
修改webpack.config.js文件
module: {
rules: [//模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}]
}
]
}
PostCSS是一个用 JavaScript 工具和插件转换 CSS 代码的工具,是一个css的预处理工具
比较常用的就是使用 PostCSS 进行添加前缀,以此为例:
安装postcss-loader
npm i -D postcss-loader
接下来,我们需要引用什么插件,就要把什么插件装上,我们需要添加前缀
npm install autoprefixer --save-dev
npm i -D postcss-loader
npm install autoprefixer --save-dev
# 以下可以不用安装
# cssnext可以让你写CSS4的语言,并能配合autoprefixer进行浏览器兼容的不全,而且还支持嵌套语法
$ npm install postcss-cssnext --save-dev
# 类似scss的语法,实际上如果只是想用嵌套的话有cssnext就够了
$ npm install precss --save-dev
# 在@import css文件的时候让webpack监听并编译
$ npm install postcss-import --save-dev
修改webpack.config.js文件
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}]
}
]
}
修改a.sass
$bgcolor:red;
.box{
background-color: $bgcolor;
font-size: 30px;
display: flex;
}
运行查看效果,F12看样式,可以看到
.box {
background-color: red;
font-size: 30px;
display: -webkit-box;
display: flex;
}
mode
必须设置为 production
,插件才有用;在开发阶段的话就用style-loader就可以了npm install --save-dev mini-css-extract-plugin
webpack.product.config.js
,即开发阶段和生成最终dist版本用两个不同的配置文件
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js', //入口
mode: 'production',
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}]
}
]
},
plugins: [
new MiniCssExtractPlugin({
// filename: devMode ? '[name].css' : '[name].[hash].css', //判断了是什么模式
// chunkFilename: devMode ? '[id].css' : '[id].[hash].css'
filename: '[name].css', // 设置最终输出的文件名,与output中filename一样
chunkFilename:'[id].css'
})
]
}
npx webpack -h
可以看webpack的帮助,可看到--config
webpack默认配置文件npx webpack --config webpack.product.config.js
(敲到webpack.p,按Tab可自动补全名称) "scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx webpack",
"dist":"npx webpack --config webpack.product.config.js"
},
filename: '[name].[hash].css'
,生成的main.css会变成mainxxxxxxxxxx.css,xxxxxxxxxx是这次打包的哈希值,是唯一标识符npm i -D optimize-css-assets-webpack-plugin
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: './src/index.js', //入口
mode: 'production',
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}]
}
]
},
plugins: [
new MiniCssExtractPlugin({
// filename: devMode ? '[name].css' : '[name].[hash].css', //判断了是什么模式
// chunkFilename: devMode ? '[id].css' : '[id].[hash].css'
filename: '[name].css', // 设置最终输出的文件名
chunkFilename:'[id].css'
})
],
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})]
}
}
npm run dist
,查看main.css,css代码都变成了一行,压缩成功npm i -D uglifyjs-webpack-plugin
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}),//压缩CSS
new UglifyJsPlugin({ //压缩JS
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})]
}
npm run dist
,此处出现错误ERROR in main.js from UglifyJs Unexpected token: name «dom», expected: punc «;» [./src/index.js:6,0][main.js:17215,8]
是因为es6需要转成es5在给webpack打包,快速解决方法是把index.js中的let改成var,再次执行,查看main.js,代码被压缩了修改webpack.product.config.js文件
filename: 'main.[hash].js', //最终打包后的文件名
filename: '[name][hash].css', // 设置最终输出的文件名
chunkFilename: '[id][hash].css'
HtmlWebpackPlugin
插件,可以把打包后的 CSS 或者 JS 文件引用直接注入到 HTML 模板中,这样就不用每次手动修改文件引用了。安装
npm install --save-dev html-webpack-plugin
修改webpack.product.config.js配置文件中的引入及plugins,从而引用插件
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: './src/index.js', //入口
mode: 'production',
output: { //输出
filename: 'main.[hash].js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name][hash].css', // 设置最终输出的文件名
chunkFilename: '[id][hash].css'
}),
new HtmlWebpackPlugin({
title: '学习webpack4.0 demo', // 默认值:Webpack App
filename: 'main.html', // 最终生成的dist中的文件的名字,默认值: 'index.html'文件名
template: path.resolve(__dirname, 'src/main.html'),//这里可以给它加模版文件,可以是index.html,也可以指定具体文件
minify: {
collapseWhitespace: true, //是否去掉空格
removeComments: true, //是否移除注释
removeAttributeQuotes: true // 移除属性的引号
}
})
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}),//压缩CSS
new UglifyJsPlugin({ //压缩JS
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="demo">我是模版文件自带的内容</div>
</body>
</html>
执行npm run dist
,查看效果,可见dist中生成了main.html文件,且引入了css和js文件
clean-webpack-plugin
是一个比较普及的管理插件。npm install clean-webpack-plugin --save-dev
const path = require('path');
+ const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
plugins: [
+ new CleanWebpackPlugin(['dist']) //想清理其他目录也可以修改名字
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
npm run dist
,查看效果。
$bgcolor:red;
.box{
background-color: $bgcolor;
font-size: 30px;
display: flex;
background: url('../assets/img/01.jpg')
}
ERROR in ./src/assets/img/01.jpg 1:0
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
npm install --save-dev file-loader
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: './src/index.js', //入口
mode: 'production',
output: { //输出
filename: 'main.[hash].js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
use: [
'file-loader'
]
},
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name][hash].css', // 设置最终输出的文件名
chunkFilename: '[id][hash].css'
}),
new HtmlWebpackPlugin({
title: '学习webpack4.0 demo', // 默认值:Webpack App
filename: 'main.html', // 最终生成的dist中的文件的名字,默认值: 'index.html'文件名
template: path.resolve(__dirname, 'src/main.html'),//这里可以给它加模版文件,可以是index.html,也可以指定具体文件
minify: {
collapseWhitespace: true, //是否去掉空格
removeComments: true, //是否移除注释
removeAttributeQuotes: true // 移除属性的引号
}
}),
new CleanWebpackPlugin()
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}),//压缩CSS
new UglifyJsPlugin({ //压缩JS
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
}
npm run dist
,可见dist中生成了一个图片文件npm install image-webpack-loader --save-dev
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: './src/index.js', //入口
mode: 'production',
output: { //输出
filename: 'main.[hash].js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false,
},
webp: {
quality: 75
}
}
},
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name][hash].css', // 设置最终输出的文件名
chunkFilename: '[id][hash].css'
}),
new HtmlWebpackPlugin({
title: '学习webpack4.0 demo', // 默认值:Webpack App
filename: 'main.html', // 最终生成的dist中的文件的名字,默认值: 'index.html'文件名
template: path.resolve(__dirname, 'src/main.html'),//这里可以给它加模版文件,可以是index.html,也可以指定具体文件
minify: {
collapseWhitespace: true, //是否去掉空格
removeComments: true, //是否移除注释
removeAttributeQuotes: true // 移除属性的引号
}
}),
new CleanWebpackPlugin()
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}),//压缩CSS
new UglifyJsPlugin({ //压缩JS
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
}
npm run dist
url-loader
功能类似于 file-loader,可以把 url 地址对应的文件,打包成 base64 的 DataURL,减少图片请求,提高访问的效率。npm install --save-dev url-loader
'file-loader'
用一个对象取代const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: './src/index.js', //入口
mode: 'production',
output: { //输出
filename: 'main.[hash].js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
use: [
{
loader: 'url-loader',
options: {
limit:90000 //设置大小多少以内的图片,引用是要转化为base64的链接
}
}
]
},
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name][hash].css', // 设置最终输出的文件名
chunkFilename: '[id][hash].css'
}),
new HtmlWebpackPlugin({
title: '学习webpack4.0 demo', // 默认值:Webpack App
filename: 'main.html', // 最终生成的dist中的文件的名字,默认值: 'index.html'文件名
template: path.resolve(__dirname, 'src/main.html'),//这里可以给它加模版文件,可以是index.html,也可以指定具体文件
minify: {
collapseWhitespace: true, //是否去掉空格
removeComments: true, //是否移除注释
removeAttributeQuotes: true // 移除属性的引号
}
}),
new CleanWebpackPlugin()
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}),//压缩CSS
new UglifyJsPlugin({ //压缩JS
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
}
'image-webpack-loader'
的配置的,但是因为频繁报错,就先删掉了。'image-webpack-loader'
原来的配置和url-loader
一起用后有冲突,在学第11的时候基本把问题解决了,详见下一节的第六步webpack-merge
的工具可以实现两个配置文件的合并,这样我们可以把开发环境和生产环境的公共配置抽取到一个公共的配置文件中。安装
npm install --save-dev webpack-merge
改造配置文件
将product的配置文件都拷贝到common里,修改webpack.common.js,留下开发阶段和生产阶段的公共部分
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
entry: './src/index.js',
module: {
rules: [
{
test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 90000 //设置大小多少以内的图片,引用是要转化为base64的链接
}
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false,
},
webp: {
quality: 75
}
}
}
]
},
]
},
plugins: [
new HtmlWebpackPlugin({
title: '学习webpack4.0 demo', // 默认值:Webpack App
filename: 'main.html', // 最终生成的dist中的文件的名字,默认值: 'index.html'文件名
template: path.resolve(__dirname, 'src/main.html'),//这里可以给它加模版文件,可以是index.html,也可以指定具体文件
minify: {
collapseWhitespace: true, //是否去掉空格
removeComments: true, //是否移除注释
removeAttributeQuotes: true // 移除属性的引号
}
}),
new CleanWebpackPlugin()
]
}
修改webpack.dev.js,留下独有部分,适当改写
const path = require('path'); //引用path模块
const merge = require('webpack-merge');
const common=require('./webpack.common');
//对外导出一个对象
let devConfig = {
mode: 'development', //代表我们现在是开发阶段
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
}
}
module.exports = merge(common,devConfig);
修改package.json中的script,修改默认执行的配置文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx webpack --config webpack.dev.js",
"dist": "npx webpack --config webpack.prod.js"
},
npm run build
,有报错,后来不断尝试发现,是'image-webpack-loader'
原来的配置中的webp未能正常把图片进行转换
ERROR in ./src/assets/img/01.jpg
Module build failed (from ./node_modules/image-webpack-loader/index.js):
Error: CoCreateInstance(MAKE_REFGUID(CLSID_WICImagingFactory), NULL, CLSCTX_INPROC_SERVER, MAKE_REFGUID(IID_IWICImagingFactory), (LPVOID*)&factory) failed 80040154
Couldn't access Windows Imaging Component (are you running Windows XP SP3 or newer?). Most formats not available. Use -s for the available YUV input.
Decoding of input data failed.
Status: 3(BITSTREAM_ERROR)
Error! Could not process file C:\Users\ADMINI~1\AppData\Local\Temp\89c3cc73-dbc6-49f7-8b9d-c0d0b66c8aad
Error! Cannot read input picture file 'C:\Users\ADMINI~1\AppData\Local\Temp\89c3cc73-dbc6-49f7-8b9d-c0d0b66c8aad'
'image-webpack-loader'
原来的配置中的webp删除修改webpack.prod.js,留下独有部分,适当改写
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const merge = require('webpack-merge');
const common = require('./webpack.common');
let prodConfig = {
mode: 'production',
output: { //输出
filename: 'main.[hash].js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name][hash].css', // 设置最终输出的文件名
chunkFilename: '[id][hash].css'
})
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}),//压缩CSS
new UglifyJsPlugin({ //压缩JS
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
}
module.exports = merge(common, prodConfig);
npm run dist
inline-source-map
选项,这有助于解释说明 js 原始出错的位置。(不要用于生产环境)const path = require('path'); //引用path模块
const merge = require('webpack-merge');
const common = require('./webpack.common');
//对外导出一个对象
let devConfig = {
mode: 'development', //代表我们现在是开发阶段
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
+ devtool: 'inline-source-map',
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
}
}
module.exports = merge(common,devConfig);
console.log(123);
npm run build
,查看控制台
npx webpack --watch
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx webpack --config webpack.dev.js",
"watch":"npx webpack --watch --config webpack.dev.js",
"dist": "npx webpack --config webpack.prod.js"
},
npm run watch
webpack-dev-server
为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。webpack-dev-server
编译速度快,编译到内存里,不写在dist中。npm install --save-dev webpack-dev-server
const path = require('path'); //引用path模块
const merge = require('webpack-merge');
const common = require('./webpack.common');
const webpack = require('webpack');
//对外导出一个对象
let devConfig = {
mode: 'development', //代表我们现在是开发阶段
output: { //输出
filename: 'main.js', //最终打包后的文件名
path: path.resolve(__dirname, 'dist')//最终main.js在哪个文件夹下
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
hot: true,
open: true
},
module: {
rules: [ //模块处理规则
{
test: /\.(sc|c|sa)ss$/,
//当引入的模块的后缀满足这个,就使用use的loader处理
use: [//处理顺序从后向前
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
plugins: loader => [
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 添加前缀
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new webpack.NamedModulesPlugin(), // 更容易查看(patch)的依赖
new webpack.HotModuleReplacementPlugin() // 替换插件
]
}
module.exports = merge(common, devConfig);
webpack-dev-server --open
devServer: {
clientLogLevel: 'warning', // 可能的值有 none, error, warning 或者 info(默认值)
hot: true, // 启用 webpack 的模块热替换特性, 这个需要配合: webpack.HotModuleReplacementPlugin插件
contentBase: path.join(__dirname, "dist"), // 告诉服务器从哪里提供内容, 默认情况下,将使用当前工作目录作为提供内容的目录
compress: true, // 一切服务都启用gzip 压缩
host: '0.0.0.0', // 指定使用一个 host。默认是 localhost。如果你希望服务器外部可访问 0.0.0.0
port: 8080, // 端口
open: true, // 是否打开浏览器
overlay: { // 出现错误或者警告的时候,是否覆盖页面线上错误消息。
warnings: true,
errors: true
},
publicPath: '/', // 此路径下的打包文件可在浏览器中访问。
proxy: { // 设置代理
"/api": { // 访问api开头的请求,会跳转到 下面的target配置
target: "http://192.168.0.102:8080",
pathRewrite: {"^/api" : "/mockjsdata/5/api"}
}
},
quiet: true, // necessary for FriendlyErrorsPlugin. 启用 quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。
watchOptions: { // 监视文件相关的控制选项
poll: true, // webpack 使用文件系统(file system)获取文件改动的通知。在某些情况下,不会正常工作。例如,当使用 Network File System (NFS) 时。Vagrant 也有很多问题。在这些情况下,请使用轮询. poll: true。当然 poll也可以设置成毫秒数,比如: poll: 1000
ignored: /node_modules/, // 忽略监控的文件夹,正则
aggregateTimeout: 300 // 默认值,当第一个文件更改,会在重新构建前增加延迟
}
}
npx webpack-dev-server --config webpack.dev.js
,然后在路由上添加/main.html
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx webpack --config webpack.dev.js",
"watch": "npx webpack --watch --config webpack.dev.js",
"start": "npx webpack-dev-server --config webpack.dev.js",
"dist": "npx webpack --config webpack.prod.js"
},
npm i -D babel-loader babel-core babel-preset-env
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/, // 加快编译速度,不包含node_modules文件夹内容
use: {
loader: 'babel-loader'
}
}
]
}
.babelrc
,其内容为{
"presets": ["env"]
}
class Temp {
show() {
console.log('this.Age :', this.Age);
}
get Age() {
return this._age;
}
set Age(val) {
this._age = val + 1;
}
}
let t = new Temp();
t.Age = 19;
t.show();
npm run build
babel-loader可以配置如下几个options:
注意:sourceMap 选项是被忽略的。当 webpack 配置了 sourceMap 时(通过 devtool 配置选项),将会自动生成 sourceMap。
babel 在每个文件都插入了辅助代码,使代码体积过大.babel 对一些公共方法使用了非常小的辅助代码,比如 _extend。 默认情况下会被添加到每一个需要它的文件中。你可以引入 babel runtime 作为一个独立模块,来避免重复引入。
npm install babel-plugin-transform-runtime --save-dev
npm install babel-runtime --save
rules: [
// 'transform-runtime' 插件告诉 babel 要引用 runtime 来代替注入。
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
}
}
]
{
"presets": ["env"],
"plugins": [
["transform-runtime", {
"helpers": true,
"polyfill": true,
"regenerator": true,
"moduleName": "babel-runtime"
}]
]
}
npm install eslint --save-dev
npm install eslint-loader --save-dev
# 以下是用到的额外的需要安装的eslint的解释器、校验规则等
npm i -D babel-eslint standard
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/, // 加快编译速度,不包含node_modules文件夹内容
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}, {
loader: "eslint-loader",
options: {
// eslint options (if necessary)
fix: true
}
}]
},
.eslintrc.js
// .eslintrc.js
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: true
},
extends: [
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
'standard'
],
globals: {
NODE_ENV: false
},
rules: {
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// 添加,分号必须
semi: ['error', 'always'],
'no-unexpected-multiline': 'off',
'space-before-function-paren': ['error', 'never'],
// 'quotes': ["error", "double", { "avoidEscape": true }]
quotes: [
'error',
'single',
{
avoidEscape: true
}
]
}
};
.eslintignore
文件,去忽略一些文件/dist/
/node_modules/
/*.js
npm run build
之后查看生成的main.js文件,发现自动修复了16.webpack的模块解析后缀和别名配置详解
17.webpack的模块的外部依赖配置
18.webpack的打包分析报表插件与优化总结
以上三课本文不作详细阐释,有兴趣可查看视频或查看于文章开头的链接查看相关笔记