1 基础配置与详解
1.1 初始化项目
mkdir ReacDemo
cd ReacDemo
mkdir src
mkdir dist
npm init -y
1.2 安装webpack
安装webpack 和webpack服务
cnpm i webpack webpack-cli webpack-dev-server -D
在项目跟目录下新建webpack配置文件webpack.config.js,配置文件的初始化内容为
module.exports = {
mode: "development",//表识开发环境
entry: ["./src/index.js"], // 入口文件
output: { // 打包后输出目录
// 输出目录
path: path.join(__dirname, "dist"),
// 文件名称
filename: "bundle.js"
},
module:{}, // loader配置
plugins:[],// 插件配置
devServer:{}//开发服务
}
1.3 babel编译ES6,JSX等
安装babel依赖包
cnpm i babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/preset-react -D
- babel-loader webpack使用babel解析用到的loader,打包转换成es5语法
- @babel/core babel核心包,使用babel解析的合并包
- @babel/preset-env babel官方预设的一些转换babel需要用到的babel依赖
- @babel/preset-react 解析react的jsx语法预设的一些依赖
关于babel的详细介绍具体可到babel官网了解
在项目跟目录下(和src同级)新建.babelrc文件,文件的内容为
{
"presets": ["@babel/preset-env","@babel/preset-react"],
"plugins": ["@babel/plugin-transform-runtime"]
}
在webpack.config.js文件中配置babel,打包转换es6及以上语法
module: {
rules:[
{
test: /\.js?$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader"
}
]
}
]
}
1.4 插件 CleanWebpackPlugin
其实 clean-webpack-plugin 很容易知道它的作用,就是来清除文件的,就是说在为生产环境编译文件的时候,先把 build或dist (就是放生产环境用的文件) 目录里的文件先清除干净,再生成新的.
cnpm install clean-webpack-plugin -D
// 注意这个引入的坑,最新版的需要这样引入,而不是直接const CleanWebpackPlugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
// 在webpack.config.js的plugins下配置
plugins: [
new CleanWebpackPlugin()
]
1.5 使用插件 HtmlWebpackPlugin
- 为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
- 可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口
插件参数详解
- title 生成html文件的标题
- filename 输出的html的文件名称
- template html模板所在的文件路径,根据自己的指定的模板文件来生成特定的 html 文件
- inject 注入选项。有四个选项值 true, body, head, false.
1. true:默认值,script标签位于html文件的 body 底部
2. body:script标签位于html文件的 body 底部(同 true)
3. head:script 标签位于 head 标签内
4. false:不插入生成的 js 文件,只是单纯的生成一个 html 文件
- favicon 给生成的 html 文件生成一个 favicon。属性值为 favicon 文件所在的路径名
- minify minify 的作用是对 html 文件进行压缩,minify 的属性值是一个压缩选项或者 false 。默认值为false, 不对生成的 html 文件进行压缩。
plugins:[
new HtmlWebpackPlugin({
//部分省略,具体看minify的配置
minify: {
//是否对大小写敏感,默认false
caseSensitive: true,
//是否简写boolean格式的属性如:disabled="disabled" 简写为disabled 默认false
collapseBooleanAttributes: true,
//是否去除空格,默认false
collapseWhitespace: true,
//是否压缩html里的css(使用clean-css进行的压缩) 默认值false;
minifyCSS: true,
//是否压缩html里的js(使用uglify-js进行的压缩)
minifyJS: true,
//Prevents the escaping of the values of attributes
preventAttributesEscaping: true,
//是否移除属性的引号 默认false
removeAttributeQuotes: true,
//是否移除注释 默认false
removeComments: true,
//从脚本和样式删除的注释 默认false
removeCommentsFromCDATA: true,
//是否删除空属性,默认false
removeEmptyAttributes: true,
// 若开启此项,生成的html中没有 body 和 head,html也未闭合
removeOptionalTags: false,
//删除多余的属性
removeRedundantAttributes: true,
//删除script的类型属性,在h5下面script的type默认值:text/javascript 默认值false
removeScriptTypeAttributes: true,
//删除style的类型属性, type="text/css" 同上
removeStyleLinkTypeAttributes: true,
//使用短的文档类型,默认false
useShortDoctype: true,
}
}),
]
- hash hash选项的作用是 给生成的 js 文件一个独特的 hash 值,该 hash 值是该次 webpack 编译的 hash 值。默认值为 false
配置webpack.config.js
// 引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Hello World app',
minify: { // 压缩HTML文件
removeComments: true, // 移除HTML中的注释
collapseWhitespace: true, // 删除空白符与换行符
minifyCSS: true// 压缩内联css
},
filename: 'index.html', // 最终创建的文件名
template: path.join(__dirname, 'src/template.html') // 指定模板路径
})
]
1.6 使用 source-map
source map就是帮助我们定位到错误信息位置的文件。正确的配置source map,能够提高开发效率,更快的定位到错误位置。详细了解请点击
在webpack.config.js中选项加上如下这句话
devtool:"cheap-module-eval-source-map",// 开发环境配置
devtool:"cheap-module-source-map", // 线上生成配置
1.7 使用 WebpackDevServer
webpack-dev-server就是在本地为搭建了一个小型的静态文件服务器,有实时重加载的功能,为将打包生成的资源提供了web服务
开发环境中我们可以启动一个devServer静态文件服务器,预览我们的项目,配置如下
- contentBase: 静态文件地址
- port: 端口号
- host: 主机
- overlay: 如果出错,则在浏览器中显示出错误
- compress: 服务器返回浏览器的时候是否启动gzip压缩
- open: 打包完成自动打开浏览器
- hot: 模块热替换 需要webpack.HotModuleReplacementPlugin插件
- inline: 实时构建
- progress: 显示打包进度
- devtool: 生成代码映射,查看编译前代码,利于找bug
- webpack.NamedModulesPlugin: 显示模块的相对路径。
devServer: {
hot: true,
contentBase: path.join(__dirname, "./dist"),
host: "0.0.0.0", // 可以使用手机访问
port: 8080,
historyApiFallback: true, // 该选项的作用所有的404都连接到index.html
proxy: {
// 代理到后端的服务地址,会拦截所有以api开头的请求地址
"/api": "http://localhost:3000"
}
}
1.8 编译css和scss
cnpm install css-loader style-loader sass-loader node-sass -D
{
test: /\.scss$/,
use: [
"style-loader", // 创建style标签,并将css添加进去
"css-loader", // 编译css
"sass-loader" // 编译scss
]
}
1.9 集成postcss
最关心的还是这有啥用啊?自动增加前缀, postcss-cssnext允许你使用未来的css特性,并做一些兼容处理
- 修改webpack配置文件下的module
cnpm install postcss-loader postcss-cssnext -D
{
test: /\.scss$/,
use: [
"style-loader", // 创建style标签,并将css添加进去
"css-loader", // 编译css
"postcss-loader",
"sass-loader" // 编译scss
]
}
- 在跟目录下新建一个postcss.config.js文件,文件内容为:
module.exports = {
plugins: {
'postcss-cssnext': {}
}
};
1.10 处理图片
- file-loader file-loader 可以指定要复制和放置资源文件的位置,以及如何使用版本哈希命名以获得更好的缓存。此外,这意味着 你可以就近管理图片文件,可以使用相对路径而不用担心部署时 URL 的问题。使用正确的配置,webpack 将会在打包输出中自动重写文件路径为正确的 URL
- url-loader 允许你有条件地将文件转换为内联的 base-64 URL (当文件小于给定的阈值),这会减少小文件的 HTTP 请求数。如果文件大于该阈值,会自动的交给 file-loader 处理
cnpm i file-loader url-loader -D
file-loader 解决css等文件中引入图片路径的问题
url-loader 当图片较小的时候会把图片BASE64编码,大于limit参数的时候还是使用file-loader 进行拷贝
{
test: /\.(png|jpg|jpeg|gif|svg)/,
use: {
loader: 'url-loader',
options: {
outputPath: 'images/', // 图片输出的路径
limit: 10 * 1024
}
}
}
2 webpack 优化
2.1 alias对文件路径优化
- extension: 指定extension之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配
- alias: 配置别名可以加快webpack查找模块的速度
修改webpack.config.js 其中resolve和配置中的entry同级
resolve: {
extension: [".js", ".jsx"],
alias: {
"@": path.join(__dirname, "src"),
pages: path.join(__dirname, "src/pages"),
router: path.join(__dirname, "src/router")
}
}
2.2 MiniCssExtractPlugin ,抽取 css 文件
如果不做配置,我们的css是直接打包进js里面的,我们希望能单独生成css文件。 因为单独生成css,css可以和js并行下载,提高页面加载效率
cnpm install mini-css-extract-plugin -D
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
{
test: /\.scss$/,
use: [
// "style-loader", // b不再需要style-loader要已经分离处理
MiniCssExtractPlugin.loader,
"css-loader", // 编译css
"postcss-loader",
"sass-loader" // 编译scss
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
]
2.3 代码分割按需加载、提取公共代码
我们现在看到,打包完后,所有页面只生成了一个bundle.js,当我们首屏加载的时候,就会很慢。因为他也下载了别的页面的js了,也就是说,执行完毕之前,页面是 完!全!空!白!的!。 如果每个页面单独打包自己的js,就可以在进入页面时候再加载自己 的js,首屏加载就可以快很多
// optimization 和配置中的entry同级
// 代码分割按需加载、提取公共代码
optimization: {
usedExports: true,
splitChunks: {
chunks: "all", // 所有的 chunks 代码公共的部分分离出来成为一个单独的文件
cacheGroups: {
// 公共代码打包分组配置
jquery: {
name: 'jquery',
test: /[\\/]node_modules[\\/]jquery[\\/]/
},
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors'
}
}
},
},
2.4 文件压缩
webpack4只要在生产模式下, 代码就会自动压缩
mode:productioin
2.5 暴露全局变量
new webpack.ProvidePlugin({
$: 'jquery', // npm
})
2.6 DllPlugin插件打包第三方类库
项目中引入了很多第三方库,这些库在很长的一段时间内,基本不会更新,打包的时候分开打包来提升打包速度,而DllPlugin动态链接库插件,其原理就是把网页依赖的基础模块抽离出来打包到dll文件中,当需要导入的模块存在于某个dll中时,这个模块不再被打包,而是去dll中获取
未完待续。。。