介绍

1. 背景

最近和部门老大,一起在研究团队【EFT - 前端新手村】的建设,目的在于:帮助新人快速了解和融入公司团队帮助零基础新人学习和入门前端开发并且达到公司业务开发水平

本文也是属于【EFT - 前端新手村】的一部分,用来帮助新人快速入门 Webpack4,内容偏基础,当然也可以作为复习材料~~这里分享给各位小伙伴啦!

2. 文章概要

由于本文篇幅较长,将分为《Webpack4入门手册(上)(共 18 章)》和《Webpack4入门手册(下)(共 18 章)》两篇文章发布,请联系起来看~

我将从最基础的【项目初始化】开始介绍,到【处理 CSS / JS / 图片】,到【热更新,打包优化】等等,一一介绍和实践。

文章共分为 18 章,关于最基础的四个核心概念,可以到我整理的另一篇文章 《Webpack4 的四个核心概念》 中学习。

《Webpack4 的四个核心概念》 https://github.com/pingan8787/Leo-JavaScript/blob/master/Cute-Webpack/guide/README.md

3. 教程目录

十、 webpack 图片 base64 和字体处理

1. 图片 base64 处理

url-loader 功能类似于 file-loader,可以将 url 地址对应的文件,打包成 base64 的 DataURL,提高访问效率。

安装插件:

npm install url-loader --save-dev

使用插件:

注意:这里需要将前面配置的 image-webpack-loader 先删除掉,在使用 url-loader

// webpack.config.js
module: {
{
test: /\.(png|svg|jpg|jpeg|gif)$/,
include: [path.resolve(__dirname, 'src/')],
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 }
}
},
]
}]
},

更多参数介绍,可访问中文官网的介绍:

2. 字体处理

字体处理的方式和图片处理方式是一样的,只是我们在配置 rules 时的 test 值不相同:

// webpack.config.js
module: {
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
include: [path.resolve(__dirname, 'src/')],
use: [ 'file-loader' ]
}
},

十一、 webpack 配置合并和提取公共配置

在开发环境(development)和生产环境(production)配置文件有很多不同,但也有部分相同,为了不每次更换环境的时候都修改配置,我们就需要将配置文件做合并,和提取公共配置。

我们使用 webpack-merge 工具,将两份配置文件合并。

安装插件:

npm install webpack-merge --save-dev

然后调整目录结构,为了方便,我们将原来 webpack.config.js 文件修改名称为 webpack.commen.js,并复制两份相同的文件出来,分别修改文件名为 webpack.prod.js 和 webpack.dev.js 。

  ├─package.json
├─dist
├─src
- ├─webpack.config.js
+ ├─webpack.common.js // webpack 公共配置文件
+ ├─webpack.prod.js // webpack 生产环境配置文件
+ ├─webpack.dev.js // webpack 开发环境配置文件

由于我们文件调整了,所以在 package.json 中,打包命令也需要调整,并且配置 mode 模式。

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "build": "npx webpack -c webpack.config.js",
+ "build": "npx webpack -c webpack.dev.js --mode development",
+ "dist": "npx webpack -c webpack.prod.js --mode production"
},

1. 调整 webpack.common.js

我们先调整 webpack.common.js 文件,将通用的配置保留,不是通用的配置删除,结果如下:

// webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.js',
module: {
noParse: function (content) {return /jquery|lodash/.test(content);},
rules: [
{
test: /\.(png|svg|jpg|jpeg|gif)$/,
include: [path.resolve(__dirname, 'src/')],
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 }
}
}]
},{
test: /\.(woff|woff2|eot|ttf|otf)$/,
include: [path.resolve(__dirname, 'src/')],
use: [ 'file-loader' ]
}]
},
plugins: [
new HtmlWebpackPlugin({
title: "leo study!",
filename: "main.html",
template: path.resolve(__dirname, 'src/index.html'),
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true,
}
}),
new CleanWebpackPlugin()
],
}

2. 安装 babel-loader

安装 babel-loader 是为了将 ES6 及以上版本的 JS 代码转换成 ES5。

npm install babel-loader @babel/core @babel/preset-env --save-dev

使用插件:

// webpack.common.js
rules: [
// ... 省略其他
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}],
exclude: /(node_modules|bower_components)/,
}
]

关于 babel-loader 更多介绍可以《查看文档》https://webpack.js.org/loaders/babel-loader/。

3. 调整 webpack.dev.js

这里我们就需要用到 merge-webpack 插件进行配置合并了:

// webpack.dev.js
const path = require('path');
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
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 }
}, {
loader: "postcss-loader",
options: {
ident: "postcss", sourceMap: true,
plugins: loader => [ require('autoprefixer')() ]
}
}, {
loader: "sass-loader",
options: { sourceMap: true }
}
]
}]
}
}
module.exports = merge(common, devConfig)

4. 调整 webpack.prod.js

同样对于生产环境的配置,我们也需要用 merge-webpack 插件进行配置合并:

// webpack.prod.js
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.js');
let prodConfig = {
mode: 'production',
output: {
filename: 'main.[hash].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.(sc|c|sa)ss$/,
use: [
MiniCssExtractPlugin.loader, {
loader: "css-loader",
options: { sourceMap: true }
}, {
loader: "postcss-loader",
options: {
ident: "postcss", sourceMap: true,
plugins: loader => [ require('autoprefixer')() ]
}
}, {
loader: "sass-loader",
options: { sourceMap: true }
}
]
}]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[hash].css',
chunkFilename: '[id].[hash].css'
}),
new OptimizeCssAssetsPlugin({}),
new UglifyJsPlugin({
cache: true, parallel: true, sourceMap: true
}),
],
}
module.exports = merge(common, prodConfig)

十二、 webpack 监控自动编译和启用 js 的 sourceMap

1. 开启 js 的 sourceMap

当 webpack 打包源代码后,就很难追踪到错误和警告在源代码的位置。

如将三个源文件打包一个 bundle 中,其中一个文件的代码报错,那么堆栈追中就会指向 bundle

为了能方便定位错误,我们使用 inline-source-map 选项,注意不要在生产环境中使用。

// webpack.dev.js
let devConfig = {
// ... 省略其他
+ devtool: 'inline-source-map'
}

2. 测试 sourceMap

为了测试是否成功,我们将 src/index.js 代码中,在第 12 行上,添加一句日志打印。

// src/index.js
// ... 省略其他
+ console.log(111)

对比下开启 sourceMap 前后的区别:

3. 开启监控自动编译

如果每次我们修改完代码,都要手动编译,那是多累的一件事。

为此我们使用 --watch 命令,让我们每次保存完,都会自动编译。

为此,我们需要在 package.json 中的打包命令添加 --watch 命令:

// package.json
- "build": "npx webpack --config webpack.dev.js",
+ "build": "npx webpack --config webpack.dev.js --watch",

这里仅对开发环境开启,生产环境不需要使用。

十三、 webpack 热更新

上一节介绍监控自动编译,当我们保存文件后,会自动编译文件,但是我们还是需要手动去刷新页面,才能看到编译后的结果。

于是为了自动编译之后,再自动重新加载,我们就可以使用 webpack-dev-server 来启动一个简单 web 服务器,实时重新加载。

1. 开启热更新

插件安装:

npm install webpack-dev-server --save-dev

使用插件:

// webpack.dev.js
const webpack = require('webpack');
const webpack = require('webpack');
let devConfig = {
// ... 省略其他
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
hot: true,
overlay: true,
open:true,
publicPath: '/',
host: 'localhost',
port: '1200'
}
plugins: [
new webpack.NamedModulesPlugin(), // 更容易查看(patch)的以来
new webpack.HotModuleReplacementPlugin() // 替换插件
]
}

启动热更新:

npx webpack-dev-server --config webpack.dev.js

常用配置:

contentBase: path.join(__dirname, 'dist'), //本地服务器所加载的页面所在的目录
clinetLogLevel: 'warning', // 可能值有 none, error, warning 或者 info (默认值)
hot:true,//启动热更新替换特性,需要配合 webpack.HotModuleReplacementPlugin 插件
host:'0.0.0.0', // 启动服务器的 host
port:7000, // 端口号
compress:true, // 为所有服务启用gzip压缩
overlay: true, // 在浏览器中显示全屏覆盖
stats: "errors-only" ,// 只显示包中的错误
open:true, // 启用“打开”后,dev服务器将打开浏览器。
proxy: { // 设置代理
"/api": {
target: "http://localhost:3000",
pathRewrite: {"^/api" : ""}
}
}

这时候我们访问 http://localhost:1200/main.html 就可以看到页面,并且修改文件,页面也会同时刷新。

2. 优化命令

我们可以将 npx webpack-dev-server--config webpack.dev.js 写到 package.json 中作为一个命令:

// package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx webpack --config webpack.dev.js --watch",
"dist": "npx webpack --config webpack.prod.js",
+ "watch": "npx webpack-dev-server --config webpack.dev.js"
},

十四、 webpack 设置代理服务器和 babel 转换及优化

1. 设置代理服务器

接着上一节,接下来给 webpack 设置代理服务器:

// webpack.dev.js
let devConfig = {
// ... 省略其他
devServer: {
// ... 省略其他
proxy: {
"/api": { // 以 '/api' 开头的请求,会跳转到下面的 target 配置
target: "http://192.168.30.33:8080",
pathRewrite: {
"^api": "/mock/api"
}
}
}
}

最后当我们请求 /api/getuser 接口,就会转发到 http://192.168.30.33:8080/mock/api

2. babel 转换及优化

babel-loader 插件的安装,已经提前介绍,在【十一、 webpack 配置合并和提取公共配置】中。

这里讲一下 babel-loader 的优化。

babel-loader 可以配置 cacheDirectory 来提高打包效率:

  • cacheDirectory:默认值 false,开启后构建时会缓存文件夹,后续从缓存中读取,将提高打包效率。

十五、 webpack 开启 Eslint

安装插件:

npm install eslint eslint-loader --save-dev

另外还需要安装 eslint 解释器、校验规则等:

npm install babel-loader standard --save-dev

2. 添加 .eslintrc.js

在项目根目录创建 .eslintrc.js,指定 eslint 规则。

这份配置内容有点多,可以去 我的 gist 复制https://gist.github.com/pingan8787/8b9abe4e04bed85f9d7846e513ed2e11 。

3. 添加 .eslintignore

在项目根目录创建 .eslintignore,指定 eslint 忽略一些文件不校验,比如内容可以是:

/dist/
/node_modules/

十六、 webpack 解析模块拓展名和别名

在 webpack 配置中,我们使用 resolve 来配置模块解析方式。

这是非常重要的,比如 import_from'lodash' ,其实是加载解析了 lodash.js 文件。

该配置就是用来设置加载和解析的方式。

在解析过程中,我们可以进行配置:

1. resolve.alias

当我们引入一些文件时,需要写很长的路径,这样使得代码更加复杂。

为此我们可以使用 resolve.alias,创建 import 或 require 的别名,使模块引入更加简单。

使用配置:

// webpack.common.js
module.exports = {
entry: './src/index.js',
+ resolve: {
+ alias: {
+ '@' : path.resolve(__dirname, 'src/')
+ }
+ }
// 省略其他
}

alias 参数的含义:

使用 @ 来替代 path.resolve(__dirname,'src/') 这个路径,接下来我们测试看看。

我们在 src/ 目录下新增 leo.js

// leo.js
export let name = 'pingan';

再到 src/index.js 中引入:

// index.js
import { name } from '@/leo.js';

这样就能正常引入。

当然,我们也可以根据实际情况,为不同路径设置不同别名

// webpack.common.js
alias: {
'@' : path.resolve(__dirname, 'src/')
+ 'assets' : path.resolve(__dirname, 'src/assets/')
}

更多参数介绍,可访问中文官网的介绍:

2. resolve.extensions

resolve.extensions 用来自动解析确定的扩展,让我们在引入模块的时候,可以不用设置拓展名,默认值为:

extensions: [".js", ".json"]

使用配置:

// webpack.common.js
import { name } from '@/leo';

十七、 webpack 配置外部拓展

当我们使用 CDN 引入 jquery 时,我们并不想把它也打包到项目中,我们就可以配置 externals 外部拓展的选项,来将这些不需要打包的模块从输出的 bundle 中排除:

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

配置 externals

// webpack.common.js
module.exports = {
// ... 省略其他
+ externals: {
+ jquery: 'jQuery'
+ },
}

通过上面配置,我们就不会把不需要打包的模块打包进来。并且下面代码正常运行:

import $ from 'jquery';
$('.leo').show();

更多参数介绍,可访问中文官网的介绍:

十八、 webpack 打包分析报表及优化总结

1. 生成报表

这里我们使用 webpack-bundle-analyzer 插件,来对打包后的文件进行数据分析,从来找到项目优化的方向。

webpack-bundle-analyzer 使用交互式可缩放树形图可视化 webpack 输出文件的大小。

安装插件:

npm install webpack-bundle-analyzer --save-dev

这个我们只有在开发环境中使用。

使用插件:

// webpack.dev.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
// ...
]
}

配置完成以后,我们执行 npm run build 打包,打包完成后,会自动打开一个数据报表分析的页面,地址是 http://127.0.0.1:8888/

webpack-bundle-analyzer 将帮助我们:

  • 看清楚我们包内都包含什么模块;

  • 准确看出每个模块的组成;

  • 最后优化它!

我们经常将报表中区域最大的模块进行优化!

2. 通过报表优化项目

我们可以看出,打包后的项目中 lodash.js 占了非常大的内存,我们就针对 lodash.js 进行优化。

我们将 lodash.js 改为 CDN 引入:

// index.html
<script src="https://cdn.bootcss.com/lodash.js/4.17.15/lodash.js"></script>

然后去设置上一节讲到的 externals

// webpack.common.js
externals: {
jquery: 'jQuery',
+ lodash: '_'
},

再打包以后,可以看到 lodash.js 已经不在包里面了:

并且打包后的文件,也能正常运行:

更多参数介绍,可访问中文官网的介绍:

参考资料

  • 《Webpack4 中文网》

  • 《2019最新Webpack4.0教程4.x 成仙之路》


《Webpack4入门手册(下)(共 18 章)》到这里结束。


总结

本文是根据 《2019最新Webpack4.0教程4.x 成仙之路》 学习总结下来的学习之路,适合入门,涉及范围较多,内容比较长,需要能静下心来学习。

内容如果有误,欢迎留言指点,我会及时修改。

本文代码最终托管在我的 github 上,点击查看(https://github.com/pingan8787/Leo-JavaScript/blob/master/Cute-Webpack/introduction/README.md)。

希望自己的文章会对各位有所帮助,也欢迎各位大佬指点。

原创系列推荐

1.JavaScript 重温系列(22篇全)

2.ECMAScript 重温系列(10篇全)

3.JavaScript设计模式 重温系列(9篇全)

4.正则 / 框架 / 算法等 重温系列(16篇全)

5.【汇总】59篇原创系列汇总

你点的每个赞,我都认真当成了喜欢

【Webpack】320- Webpack4 入门手册(共 18 章)(下)的更多相关文章

  1. 【Webpack】319- Webpack4 入门手册(共 18 章)(上)

    介绍 1. 背景 最近和部门老大,一起在研究团队[EFT - 前端新手村]的建设,目的在于:帮助新人快速了解和融入公司团队,帮助零基础新人学习和入门前端开发并且达到公司业务开发水平. 本文也是属于[E ...

  2. 从新手到高手c++全方位学习 pdf + 视频教程 共18章

    淘宝已经和谐了这个网站,原网址:https://item.taobao.com/item.htm?spm=a1z09.8149145.0.0.mb00D0&id=17350311256& ...

  3. 【Cute-Webpack】Webpack4 入门手册(共 18 章)

    介绍 1. 背景 最近和部门老大,一起在研究团队[EFT - 前端新手村]的建设,目的在于:帮助新人快速了解和融入公司团队,帮助零基础新人学习和入门前端开发并且达到公司业务开发水平. 本文也是属于[E ...

  4. 《Python学习手册 第五版》 -第18章 参数

    在函数的定义和调用中,参数是使用最多喝最频繁的,本章内容就是围绕函数的参数进行讲解 本章重点内容如下: 1.参数的传递 1)不可变得参数传递 2)可变得参数传递 2.参数的匹配模式 1)位置次序:从左 ...

  5. DPDK2.1 linux上开发入门手册

    1引言 本文档主要包含INTEL DPDK安装和配置说明.目的是让用户快速的开发和运行程序.文档描述了如何在不深入细节的情况下在linux应用开发环境上编译和运行一个DPDK应用程序. 1.1文档总览 ...

  6. webpack4入门配置

    下面是抄过来的,方便自己翻越 webpack4.x入门配置   1.首先npm install webpack webpack-cli webpack-dev-server -g (mac电脑用超级管 ...

  7. webpack4入门到进阶案例实战课程

    愿景:"让编程不在难学,让技术与生活更加有趣" 更多教程请访问xdclass.net 第一章 webpack4前言 第一集 webpack4入门到进阶案例实战课程介绍 简介:讲述w ...

  8. react webpack.config.js 入门学习

    在学习react 的时候必然会用到webpack打包工具,webpack的快速入门另外一篇文章中有记录,这里只记录webpack.config.js文件,因为每个项目下都必须配置,通俗的讲,它的作用就 ...

  9. webpack4入门

    前提 已安装node(版本号>4.0,已自带NPM) mac机器 有一个空目录 无webpack.config.js配置打包 快速构建package.json文件. npm init -y 安装 ...

随机推荐

  1. 如何对 React 函数式组件进行优化

    文章首发个人博客 前言 目的 本文只介绍函数式组件特有的性能优化方式,类组件和函数式组件都有的不介绍,比如 key 的使用.另外本文不详细的介绍 API 的使用,后面也许会写,其实想用好 hooks ...

  2. nyoj 366 D的小L (全排列)

    D的小L 时间限制:4000 ms  |  内存限制:65535 KB 难度:2   描述       一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给 ...

  3. nyoj 103-A+B Problem II (python 大数相加)

    103-A+B Problem II 内存限制:64MB 时间限制:3000ms 特判: No 通过数:10 提交数:45 难度:3 题目描述: I have a very simple proble ...

  4. hopper反汇编工具的逆向伪代码功能并不理想

    hopper的逆向代码功能并不如想象中那么好,尤其是在逆向c++代码时.对于从ObjC进入iOS开发又不太清楚运行时的人员来说,hopper可以将反汇编码输出成[obj selector:what]这 ...

  5. opencv MatchTemplate()模板匹配寻找最匹配部分

    通常,随着从简单的测量(平方差)到更复杂的测量(相关系数),可以获得越来越准确的匹配,然而,这同时也会以越来越大的计算量为代价.比较科学的方法是对所有这些方法多次测试实验,以便为自己的应用选择同时兼顾 ...

  6. 【Linux系列】Centos7安装Samba并将工作区挂载到win(八)

    目的 本文主要介绍以下两点: 一. 安装Samba 二. 挂载到window 演示 一. 安装Samba Samba是基于smb协议的,主要作用是实现跨平台文件传输. 安装 yum install - ...

  7. Java 添加、读取、修改、删除Word文档属性

    Word文档属性包括常规.摘要.统计.内容.自定义等,其中摘要包括标题.主题.作者.经理.单位.类别.关键词.备注等项目,通过设置这些摘要信息或自定义属性可方便对文档的管理.本文中将主要介绍对文档摘要 ...

  8. java.lang.String 的 + 号操作到底做了什么事情?

    前言  在之前的面试经历中,对于String的考察还是挺频繁的,大致考察以下几个知识点: String 常量池 new String() == 和 equals 的区别 native 方法 Strin ...

  9. Windows Server 2008 服务器重启后卡死在Windows Update 页面问题处理

    Windows Update 服务器 服务器是联想RD640 操作系统Windows Server 2008 R2 Enterprise版 补丁版本是SP1 远程windows服务器时,一直处于远程建 ...

  10. android clipChildren 的使用与遇到的困难

    案例 在一次我写画板模块的时候,布局比较普通,但是需要子元素溢出父元素.其中一小块布局如下所示: 红色部分需要溢出,这个时候我想到了clipChildren. clipChildren 就是说我可以不 ...