参考 webpack文档 从0到1搭建一个自己的webpack项目。网上教程很多啊,如果看完还不懂的小伙伴,希望你动手照着文档多倒腾几遍,我这个直接上的快速入门完整 demo,不是基础的概念,以及必要的依赖环境,比如node。
第一步:创建项目结构
首先我们创建一个目录,初始化 npm,然后 在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack):
注:不推荐全局安装,因为你可能会有不同的webpack版本的项目,如果你全局安装的话,版本就固定了,你可能处理别的不同版本的项目的时候会报错
// 创建一个文件
mkdir webpack-demo && cd webpack-demo
// 初始化一个package.json
npm init -y
//本地化webpack 安装 开发依赖
npm i -D webpack
// 4.0以后 新加的,需要安装一个wenpack cli
npm i -D webpack-cli
初始化工作完毕(截图)
第二步:添加dist和src文件以及index.htm 和inde.js
第三步:安装 loadash 依赖和编写 js 文件
loadsh 使用处理我们的js编译的
npm install --save lodash
编写:src/index.js 文件
// 引入loadsh
import _ from 'lodash';
function createDomElement() {
var dom = document.createElement('div');
//使用了loadsh 的 join() 方法,将 字符串 用 空格进行 拼接
dom.innerHTML = _.join(['你好', 'webpack'], '');
return dom;
}
// 将元素添加到body里
document.body.appendChild(createDomElement());
编写 index.html
<!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>起步</title>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
**第四步:编写 webpack 配置文件 webpack.config.js **
这里我新加一个config文件夹,用来放这个配置文件(因为后边还要添加开发和测试环境的配置,我这里就直接放到一个文件下了)
编写webpack.config.js(简单写了点注释)
// 引入path 模块
const path = require('path')
module.exports = {
// 配置入口
entry: './../src/index.js',
// 配置环境(这里是开发)
mode: 'development',
// 配置出口
output: {
filename: 'main.js', // 文件名字
path: path.resolve(__dirname,'../dist') // 文件路径
}
}
最后执行
npx webpack
编译后的目录
在浏览器打开index.html,就看到index.js中通过loadsh的join()方法添加的字符串(这个地址栏的地址不是webpack的热加载服务,是我在vscode里起动的live-server服务,你直接浏览器打开你本地的index.html就好,我们还没有到配置热加载服务那一步,可能跟你的有点不一样)
下边处理非 js 模块
**第五步:加载 CSS 文件 **
-D是开发依赖, -S 是生产依赖, i是install的缩写 这里都是简写,全拼是–save -dev和–save
第一步:安装 css 和 style 模块解析的依赖 style-loader 和 css-loader
npm i -D style-loader css-loader
第二步: 添加 css 解析的 loader
修改webpack.config.js文件,添加module模块
// 引入path 模块
const path = require("path");
module.exports = {
// 配置入口
entry: "./../src/index.js",
// 配置环境(这里是开发)
mode: "development",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "../dist") // 文件路径
},
// 设置模块的处理
module: {
// 处理规则
rules: [
// 其中一条规则
{
test: /\.css$/, // 正则表达式,表示的意思是匹配到文件名的后缀是.css的文件
use: ["style-loader", "css-loader"] // use就是使用这里边的loader进行处理 解析顺序是从后向前
}
]
}
};
第三步:在src文件下添加一个style文件夹,创建文件index.css,并在index.js中引入
这里重新改一下项目目录,删除了config,style文件夹让项目结构简单一些,后边再进行抽离(截图,修改后的目录),别忘记修改index.js中引入index.css的路径
最后再vscode的终端执行npx webpack 命令,终端快速打开快捷键
ctrl + esc下边的那个波浪线按键
刷新本地的index.html,
加载 Sass 文件(less不写了,同Sass配置)
第一步:安装 sass-loader node-sass
npm install sass-loader node-sass webpack --save-dev
第二步:修改webpack.js
// 引入path 模块
const path = require("path");
module.exports = {
// 配置入口
entry: "./src/index.js",
// 配置环境(这里是开发)
mode: "development",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: { // 设置模块的处理
// 处理规则
rules: [
// 其中一条规则
{
test: /\.(sc|sa|c)ss$/, // 正则表达式,表示的意思是匹配到文件名的后缀是.css||sass||scss的文件
use: ['style-loader', 'css-loader', 'sass-loader'] // use就是使用这里边的loader进行处理 解析顺序是从后向前
}
]
}
};
在src下创建一个scss文件(截图)
a.scss文件
@charset 'utf-8';
// 定义变量
$bgcolor:#f90;
$textcolor:red;
body{
background-color: $bgcolor;
}
.box {
color: $textcolor;
}
修改index.js文件,
将引入的index.css换成a.scss文件
// 引入css样式
import "./a.scss";
执行npx webpack(颜色有点丑啊,见谅哈)
创建 Source Map
因为我们打包项目的时候,会把css 样式都打包到一块,这就让我们开发时不好调试,不能找到具体的某一个报错或者找到具体的某个样式所在的行数,所以使用Source Map来解决这个问题
上边这个截图可以看一下,你看不到你的样式具体在哪个文件下,第几行,同样你的js文件也是这样的,就不截图了下边看看Source Map怎么玩
直接修改webpack.config.js, 添加
{
loader: “css-loader”,
options: {
sourceMap: true
}
},
// 引入path 模块
const path = require("path");
module.exports = {
// 配置入口
entry: "./src/index.js",
// 配置环境(这里是开发)
mode: "development",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.scss$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
sourceMap: true
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
}
]
}
};
接着执行npx webpack(这样就可以看到具体的哪一行了)
** 处理css中自动添加浏览器前缀**
安装
npm i -D postcss-loader
npm install autoprefixer --save-dev
修改webpack.config.js,在module属性中添加下边这个对象
// 配置postcss-loader
{
loader: 'postcss-loader',
options: {
ident: 'postcss', // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [ // 插件,可以设置多个
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 这个是市场占有度在中国
]
}
},
修改a.scss,给box 添加一个display:flex属性
@charset 'utf-8';
// 定义变量
$bgcolor:#f90;
$textcolor:red;
body{
background-color: $bgcolor;
}
.box {
color: $textcolor;
display: flex;
}
运行 npx webpack ,可以看到浏览器前缀自动处理了
样式文件单独抽离成专门的单独文件
安装
首先以下的 css 的处理我们都把 mode 设置为 production。
webpack4 开始使用: mini-css-extract-plugin插件, 1-3 的版本可以用: extract-text-webpack-plugin
抽取了样式,就不能再用 style-loader注入到 html 中了。
npm install --save-dev mini-css-extract-plugin
这里就不再修改webpack.config.js了,而是新建一个webpack.prod.js文件,(及生产环境配置)
webpack.prod.js代码:
// 引入path 模块
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") // 文件路径(绝对路径)
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: 'postcss-loader',
options: {
ident: 'postcss', // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [ // 插件,可以设置多个
require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css', // 设置最终输出的文件名
chunkFilename: '[id].css'
})
]
};
目录截图
最后执行 npx webpack --config webpack.prod.js
就会看到dist 目录下多了一个main.css文件,这个时候,你需要手动把这个css文件在index.html中手动引入(截个图)
** CSS,js代码编译后压缩**
安装
npm i -D optimize-css-assets-webpack-plugin
npm i -D uglifyjs-webpack-plugin
修改webpack.prod.js文件
// 引入path 模块
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
// 配置入口
entry: "./src/index.js",
// 配置环境(这里是开发)
mode: "production",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [
// 插件,可以设置多个
require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css", // 设置最终输出的文件名
chunkFilename: "[id].css"
})
// webpack 处理css缓存,添加一个hash
// new MiniCssExtractPlugin({
// filename: '[name][hash].css',
// chunkFilename: '[id][hash].css'
// })
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}), // css压缩
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
};
修改index.js
// 引入loadsh
import _ from 'lodash';
// 引入css样式
import "./a.scss"; // 需要加载loadder => css-loader style-loader
function createDomElement() {
var dom = document.createElement('div');
//使用了loadsh 的 join() 方法,将字符串进行用 空格进行 拼接
dom.innerHTML = _.join(['你好', 'webpack'], '');
// 添加一个class
dom.classList.add('box')
return dom;
}
// 将元素添加到body里
document.body.appendChild(createDomElement());
执行 npx webpack --config webpack.prod.js 命令就会看到代码压缩了
注意:因为代码压缩我们只在线上环境时才会进行压缩,以缩小代码体积,所有要配置在开发环境中,浏览器一般都会有缓存,如果想处理混存问题,就要使用hash这个东西,同样js文件也是一样
添加别名
由于每次都运行 npx webpack --config webpack.prod.js这个指令,下边配置一下指令
打开package.json找到scripts配置,添加如下代码
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "npx webpack",
"build": "npx webpack --config webpack.prod.js"
},
以后就直接运行 npm run build
解决 CSS 文件或者 JS 文件名字哈希变化的问题
由于要处理浏览器缓存问题,文件名就采用了hash这种模式,但是哪次生成的都是不同的文件名,我们不可能手动去更改这个名字,就需要来处理这个问题
安装
npm install --save-dev html-webpack-plugin
修改webpack.prod.js文件
// 引入path 模块
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 配置入口
entry: "./src/index.js",
// 配置环境(这里是开发)
mode: "production",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [
// 插件,可以设置多个
require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
chunkFilename: "[id][hash].css"
}),
new HtmlWebpackPlugin({
title: "Webpack App", // 默认值:Webpack App
filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true // 移除属性的引号
}
})
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}), // css压缩
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
};
现在的文件目录
执行npm run build,以后就自己处理打包的文件名修改了
处理dist目录
由于你每次打包项目后,你会发现每执行一次指令就会多处一个新文件,这页需要我们去处理一下,每次重新打包都先把dist文件进行清除
安装
npm install clean-webpack-plugin --save-dev
修改webpack.config.js文件
// 引入path 模块
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
// 配置入口
entry: "./src/index.js",
// 配置环境(这里是开发)
mode: "production",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [
// 插件,可以设置多个
require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
chunkFilename: "[id][hash].css"
}),
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: "Webpack App", // 默认值:Webpack App
filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true // 移除属性的引号
}
})
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}), // css压缩
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
};
处理引入图片和图片压缩处理
安装 file-loader 处理文件的导入
npm install --save-dev file-loader
npm install image-webpack-loader --save-dev
修改配置文件,在module属性中的rules中添加如下代码
{
test: /\.(png|svg|jpg|gif)$/,
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
}
}
}
]
}
Base64处理图片
安装
npm install --save-dev url-loader
此时的 webpack.config.js 配置文件代码
// 引入path 模块
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
// 配置入口
entry: "./src/index.js",
// 配置环境(这里是开发)
mode: "production",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [
// 插件,可以设置多个
require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
},
{
// test: /\.(png|svg|jpg|gif)$/,
test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/, // 这个就是即处理图片,又处理字体图标库了
use: [
{
loader: "url-loader", // 根据图片大小,把图片优化成base64
options: {
limit: 10000 // 做个限制,小于10kb进行处理
}
},
{
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", // webpack 处理css缓存,添加一个hash
chunkFilename: "[id][hash].css"
}),
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
title: "Webpack App", // 默认值:Webpack App
filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true // 移除属性的引号
}
})
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}), // css压缩
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
};
以上就是css 图片 js 等的处理,下边进行处理拆分webpack的配置,因为我们有开发,生产和和测试环境,对于相同的配置进行抽离
webpack拆分处理
webpack-merge 的工具可以实现两个配置文件的合并,这样我们就可以进行拆分文件了
安装
npm install --save-dev webpack-merge
修改项目目录
新建 webpack.common.js webpack.dev.js文件
webpack.common.js代码
// 引入path 模块
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
// 配置入口
entry: "./src/index.js",
module: {
rules: [
{
test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/, // 这个就是即处理图片,又处理字体图表库了
use: [
{
loader: "url-loader", // 根据图片大小,把图片优化成base64
options: {
limit: 10000
}
},
{
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 CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
title: "Webpack App", // 默认值:Webpack App
filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true // 移除属性的引号
}
})
]
};
webpack.dev.js 代码
// 引入path 模块
const path = require("path");
// 引入合并
const merge = require('webpack-merge')
const common = require('./webpack.common')
let devConfig = {
// 配置环境(这里是开发)
mode: "development",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.(sc|c|sa)ss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [
// 插件,可以设置多个
require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
},
]
}
};
module.exports = merge(common, devConfig);
webpack.prod.js代码
// 引入path 模块
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const merge = require('webpack-merge')
const common = require('./webpack.common')
let prodConfig = {
// 配置环境(这里是开发)
mode: "production",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [
// 插件,可以设置多个
require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
chunkFilename: "[id][hash].css"
}),
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}), // css压缩
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
};
module.exports = merge(common, prodConfig);
好了,改造完成
js 使用 source map
此功能只在开发模式下使用,添加如下代码
devtool: ‘inline-source-map’,(直接截图了)
你可以在index.js 故意写一段错误的代码,然后npm run build ,我这里看到如下
使用 webpack-dev-server 和热更新
官方的watch 监听,每次我们修改 js 或者 css 文件后,要看到修改后的 html 的变化,需要我自己重新刷新页面,这里就不介绍了。
安装
npm install --save-dev webpack-dev-server
我们只在开发阶段进行热加载及更新
webpack.dev.js修改
// 引入path 模块
const path = require("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") // 文件路径(绝对路径)
},
devtool: 'inline-source-map',
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 // 默认值,当第一个文件更改,会在重新构建前增加延迟
}
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.(sc|c|sa)ss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
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);
启动: npx webpack-dev-server --config webpack.dev.js
添加npm run start 指令:
打开package.json:
"start": "npx webpack-dev-server --config webpack.dev.js",
此时你打开,会发现浏览打开找不到文件,这个是因为
因为默认是index.html,这里你将main.html 修改为index.html就可以了,当然这个也是可以配置的
启用babel转码
安装
npm i -D babel-loader babel-core babel-preset-env
根目录下添加.babelrc 文件
.babelrc代码
{
"presets": ["env"]
}
这里你运行npm run dev 会报错的,因为这个时候的bable是8.0以上的版本,所以配置有问题,你需要执行babel-loader的版本
npm install ‘babel-loader@7’
重新安装一下就好了
在index.js中写点es6 代码试试吧
let a = 10,
b = 1,
c = 2;
console.log(a)
console.log(b)
console.log(c)
没有任何问题,这里已经转译过来了
Babel优化
安装
npm install babel-plugin-transform-runtime --save-dev
npm install babel-runtime --save
修改common.js
{
test: /\.js$/,
exclude: /node_modules/, // 加快编译速度,不包含node_modules文件夹内容
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
}
}
},
修改.babelrc
{
"presets": ["env"],
"plugins": [
["transform-runtime", {
"helpers": true,
"polyfill": true,
"regenerator": true,
"moduleName": "babel-runtime"
}]
]
}
resolve()解析配置别名
在common.js中
resolve: {
extensions: [".js", ".json"], // 默认值: [".js",".json"]
alias: {
"@": path.resolve(__dirname, "src/") //配置别名
}
},
eslint配置不说了
说一下扩展
比如你想引入jquery ,需要使用 externals
在index.html 中通过cdn引入jquery 或者npm 安装下
<script
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous"
></script>
打印结果
所有基本配置完毕,这里总结一下使用到的配置,贴一个完整的package.json
最终的package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"babel-runtime": "^6.26.0",
"lodash": "^4.17.11",
"postcss-loader": "^3.0.0"
},
"devDependencies": {
"autoprefixer": "^9.4.2",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.1",
"babel-loader": "^7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"clean-webpack-plugin": "^1.0.0",
"css-loader": "^2.0.0",
"eslint": "^5.10.0",
"eslint-loader": "^2.1.1",
"file-loader": "^2.0.0",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^4.6.0",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"sass-loader": "^7.1.0",
"standard": "^12.0.1",
"style-loader": "^0.23.1",
"uglifyjs-webpack-plugin": "^2.0.1",
"url-loader": "^1.1.2",
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10",
"webpack-merge": "^4.1.5"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npx webpack-dev-server --config webpack.dev.js",
"dev": "npx webpack --config webpack.dev.js",
"build": "npx webpack --config webpack.prod.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}
webpack.common.js
// 引入path 模块
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
// 配置入口
entry: "./src/index.js",
resolve: {
extensions: [".js", ".vue", ".json"], // 默认值: [".js",".json"]
alias: {
"@": path.resolve(__dirname, "src/") //配置别名
}
},
externals: {
jquery: "jQuery"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // 加快编译速度,不包含node_modules文件夹内容
loader: "babel-loader",
options: {
cacheDirectory: true
}
},
{
test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/, // 这个就是即处理图片,又处理字体图表库了
use: [
{
loader: "url-loader", // 根据图片大小,把图片优化成base64
options: {
limit: 10000
}
},
{
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 CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
title: "Webpack App", // 默认值:Webpack App
filename: "index.html", // 默认值: 'index.html' 最后打包后生成的文件名
template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true // 移除属性的引号
}
})
]
};
webpack.dev.js
// 引入path 模块
const path = require("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") // 文件路径(绝对路径)
},
devtool: 'inline-source-map',
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 // 默认值,当第一个文件更改,会在重新构建前增加延迟
}
},
module: {
// 设置模块的处理
// 处理规则
rules: [
{
test: /\.(sc|c|sa)ss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
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.prod.js
// 引入path 模块
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const merge = require('webpack-merge')
const common = require('./webpack.common')
let prodConfig = {
// 配置环境(这里是开发)
mode: "production",
// 配置出口
output: {
filename: "main.js", // 文件名字
path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
},
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true
}
},
// 配置postcss-loader
{
loader: "postcss-loader",
options: {
ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
sourceMap: true, // 启用sourceMap
plugins: loader => [
// 插件,可以设置多个
require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
chunkFilename: "[id][hash].css"
}),
],
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({}), // css压缩
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
})
]
}
};
module.exports = merge(common, prodConfig);
最后的目录