一 webpack是模块打包工具
【webpack官方文档查看:webpack模块的概念 、模块的方法和变量】
1. 面向过程开发
随着业务代码增加,后期维护困难。可能要在几千行代码里去找错改错。
cd Desktop
touch index.html // ! 初始化html文档
touch index.js
2. 面向对象开发
cd Desktop
mkdir lesson
cd lesson
touch index.html // ! 初始化html文档
touch index.js
touch header.js
touch sidebar.js
touch content.js
// ES Module 模块引入方式
// 但是原生浏览器不识别import语句。
// 这个时候webpack就登场了!webpack翻译以下语句,浏览器就识别了。
import Header from './header.js'
import Sidebar from './sidebar'
import Content from './content'
var dom = document.getElementById('root')
new Header();
new Sidebar();
new Content();
当使用面向对象开发时,如上面使用到了export / import语法(ES Module 模块引入方式),但是原生浏览器不识别import语句。这个时候webpack就登场了!webpack翻译之后语句之后浏览器就识别了。下面开始安装并使用webpack。
3. 安装Node和NPM
webpack是基于node开发的模块打包工具,所以它本质上是由node实现的。提升webpack打包速度的2个重要的方法: 1 node版本最新 2 webpack版本最新。
(1) Mac下卸载node
// 一.在终端依次输入以下命令
sudo npm uninstall npm -g
sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.*
sudo rm -rf /usr/local/include/node /Users/$USER/.npm
sudo rm /usr/local/bin/node
sudo rm /usr/local/share/man/man1/node.1
sudo rm /usr/local/lib/dtrace/node.d
// 二.验证是否成功
// 如果上述代码你已经按照顺序去执行一遍了,那我们就需要来验证一下我们有没有删除成功。
// 如果出现一下结果说明我们就是删除成功了。
node -v //not found
npm -v //not found
// 三.接下来就可以去官网下载我们需要的版本
https://nodejs.org/en/
(2) Mac下安装node
// (1)安装node版本管理模块n
sudo npm install n -g
//下边步骤请根据自己需要选择
//(2)安装稳定版
sudo n stable
//(3)安装最新版
sudo n latest
//(4) 版本降级/升级
sudo n 版本号 //例如:sudo n 10.13.0
4. webpack的环境搭建
(1) 创建package.json
// 依次执行如下命令 生成一个package.json文件
mkdir webpack-demo
cd webpack-demo
npm init // npm init -y
// 手动配置package.json ("private": true,)
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"private": true,
// "main": "index.js", // 删除是因为项目是我们自己使用,没必要向外暴露一个js文件
(2) 安装webpack和webpack-cli
// 注意:webpack和webpack-dev-server有版本兼容性的要求
// webpack 3.x 要使用 webpack-dev-server 2.x
// webpack 4.x 要使用 webpack-dev-server 3.x
// 全局安装指定版本的webpack-dev-server(局部安装去掉-g)
npm install webpack-dev-server@3.11.3 -g
a. 全局安装(不推荐)
// 卸载
npm uninstall webpack webpack-cli -g
// 一起安装
npm install webpack webpack-cli -g
// 或者分别单独安装
npm install webpack --save
npm install webpack-cli --save-dev
// 全局安装指定版本的webpack
npm install webpack@4.25.1 -g // npm install webpack --save
// 全局安装指定版本的webpack-cli
npm install webpack-cli@3.1.2 -g // npm install webpack-cli --save-dev
// 查看版本号 -- 全局查找
webpack -v
b. 在项目内安装webpack(推荐)
// 卸载
npm uninstall webpack webpack-cli --save-dev
// 安装
npm install webpack webpack-cli --save-dev // 二者等价
npm install webpack webpack-cli -D // 二者等价
// 安装指定版本的webpack到package.json文件中
npm info webpack // 查看webpack的版本号信息,确认是否存在4.26.0版本
npm install webpack@4.26.0 webpack-cli@3.1.2 --save-dev
// 查看版本号 -- 当前文件夹的node_modules下查找
npx webpack -v
npx webpack-cli -v
安装完成之后在package.json文件里可以看到对应的版本信息,如下。
然后执行以下命令打包:
npx webpack index.js // 用webpack翻译index.js文件,以便识别important语法。
执行完npx webpack index.js之后,lesson文件夹下会生成dist/main.js文件,这个才是浏览器能识别的js文件。
至此,index.html就可以在浏览器运行了。所以webpack就是一个翻译器吗?答案是否定的。那webpack到底是什么呢?
5. webpack是模块打包工具
在上面的例子中,webpack其实并不能翻译其他的语法(只认识import),它的功能是把Header、Sidebar、Content三个模块打包到了一起,生成一个最终的js文件。所以是一个模块打包工具。我们在写JS的时候,不仅有ES Module这样的语法,还有CommonJS(Nodeh中最常用的模块引入规范)这样的语法,另外还有CMD、AMD这样的规范。webpack都能识别。
// 引入方式
// ES Module
import Header from './header.js'
import Sidebar from './sidebar'
import Content from './content'
// CommonJS
var Header = require('./header.js')
var Sidebar = require('./sidebar.js')
var Content = require('./content.js')
// 导出方式
// ES Module
// export default Header;
// export default Sidebar;
// export default Content;
// CommonJS
module.exports = Header
module.exports = Sidebar
module.exports = Content
webpack刚推出的时候仅仅是js的模块打包工具。随着webpack的发展,现在可以打包任何形式的模块文件。比如.css文件、.jpg/.png等格式的图片文件,等等其他任何形式的模块文件。
二 webpack.config.js配置文件
【webpack官方文档查看:入口和上下文(entry-context)、输出(output)、webpack的安装和起步】
1. entry和output配置
在默认webpack的配置下,我们使用npx webpack index.js打包js入口文件。
cd Desktop // 桌面
mkdir lesson // 在桌面创建lesson文件夹
cd lesson
touch index.html // 创建index.html文件 (! 初始化html文档 )
touch index.js // 创建index.js
touch header.js // 创建header.js
touch sidebar.js // 创建sidebar.js
touch content.js // 创建sidebar.js
npm init // 创建package.json文件 默认一路回车
npm install webpack@4.26.0 webpack-cli@3.1.2 -D // 安装webpack和webpack-cli
npx webpack index.js // 用webpack打包index.js
有时候我们需要自定义配置文件该怎么办呢?如下:在lesson文件夹下新建webpack.config.js文件,并做如下配置。然后执行npx webpack打包就可以了。
// 当执行npx webpack时,webpack内部会寻找webpack.config.js文件
// 并根据entry和output的配置选择入口js文件和打包之后输出的路径和文件名。
npx webpack // 当在webpack.config.js文件里声明了entry和output之后使用
在默认情况下创建的webpack配置文件名称是webpack.config.js,同时我们也可以自定义文件名。比如webpackconfig.js,那我们打包的时候执行如下命令就可以了。
npx webpack --config webpackconfig.js // 以webpackconfig.js为配置文件进行打包
(1)单entry、单output打包
(2)多entry、多output打包
2. 项目目录的优化及npm run bundle的实现
在package.json文件的script对象里,配置bundle快捷命令。这样以后用webpack打包模块的时候就可以执行如下命令了
npm run bundle // 二者等价
npx webpack // 二者等价
// 注意
// webpack会优先在当前项目下的node_modules里去查找webpack,如果没有找到才会到全局去查找。
script: { // 在package.json里script对象作如下配置
bundle: 'webpack' // 这里是webpack,而不是npx webpack。
}
package.json的配置
webpack.config.js的mode和entry配置详解
3. webpack的三种运行方式
// 1 全局安装
webpack index.js
// 2 局部安装
npx webpack index.js
// 3 npm scripts
npm run bundle // package.json文件配置
我们在安装webpack的时候,同时还安装了webpack-cli,它的作用是使得我们在命令行里可以正常使用webpack的命令。
三 webpack之Loader
1. 什么是Loader
webpack默认是只能识别并打包js模块,如果想打包css、jpg等其他模块,需要使用Loader。
所以Loader是一个打包方案,它知道对于一个特定的文件,webpack应该如何的进行打包。webpack可以借助于Loader打包对应的资源。
2. 使用Loader打包静态资源
(1)file-loader和url-loader的使用和区别
url-loader可以实现file-loader的一切功能,不一样的是它会把图片转化为base64的字符串直接放到bundle.js里。好处是不用单独请求图片地址少了一次http请求,不好的地方是导致bundle.js文件变大。建议:图片很小时,可以转化为base64放到js文件,过大时,还是以图片的格式单独存放。可以使用limit配置实现。
【webpack官方文档查看:占位符placeholder、file-loader文档 、url-loader文档】
loader的安装
npm install file-loader -D
npm install url-loader -D
// 打包不同的模块module,使用相应的Loader
module: {
rules: [{
// test: /\.jpg$/, // 文件后缀.jpg 识别到jpg格式的图片时,借助file-loader打包,移动到dist目录下
test: /\.(jpg|png|gif)$/,
use: {
loader: 'file-loader',
options: {
// [name]_[hash].[ext] 这个被称为placeholder 占位符
name: '[name]_[hash].[ext]', // 打包生成的文件名称和后缀跟原始文件保持一致
outputPath: 'images/'
}
}
},{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/',
limit: 2048 // 2048个字节 2kb 小于2kb转化为base64,大于2kb会以图片格式单独存放
}
}
}]
},
(2)打包样式
【webpack官方文档查看:css、iconfont的打包、css-loader、sass-loader、style-loader、postcss-loader】
四 webpack之plugins-让打包更便捷
1. 什么是plugin
在webpack运行到某个时刻的时候帮你做一些事情(类似于vue的声明周期函数)。
【webpack官方文档查看:管理输出-设置 HtmlWebpackPlugin、html-webpack-plugin】
(1)HtmlWebpackPlugin
HtmlWebpackPlugin会在打包结束后,自动生成一个html文件,并把打包生成的js自动引入到这个html文件中。
npm install --save-dev html-webpack-plugin
(2)clean-webpack-plugin
作用是打包前先删除之前的dist目录
npm install clean-webpack-plugin@1.0.0 -D
(3)使用
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
main: './src/index.js'
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CleanWebpackPlugin(['dist'])
],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
五 webpack之SourceMap
1. sourceMap的作用
它是一个映射关系,假如说打包后的dist目录下的main.js文件中第96行出错,实际上对应的是打包前的src目录下index.js中的第1行出错了,sourceMap做了一个映射,便于开发过程中排查问题。devtool文档
source-map 代码在第几行第几个字符出错,并生成对应的.map文件(打包后出错的地方跟源文件出错的地方建立映射关系的文件)
如果不使用sourceMap,只知道打包代码出错了,但不知道源代码的位置。
- mode: development
development环境下最佳推荐: cheap-module-eval-source-map。提示的错误比较全,同时打包速度比较快。 - mode: production
production环境下最佳推荐: cheap-module-source-map(一般不用devtool)
2. 各个方式的区别
(1) source-map
1 生成.map的文件
2 代码在第几行第几个字符出错
3 将打包后的js代码出错的地方跟业务代码建立映射关系
4 耗费性能
(2) inline-source-map(inline的作用)
1 不生成单独的.map文件(内容被以base64位的格式存放在生成的js文件里)
2 代码在第几行第几个字符出错
3 将打包后的js代码出错的地方跟业务代码建立映射关系
4 耗费性能
(3) cheap-inline-source-map(cheap的作用)
1 不生成单独的.map文件(内容被以base64位的格式存放在生成的js文件里)
2 代码在第几行出错
3 只映射业务代码和打包后的js代码,不映射第三方代码和打包后的js代码
4 提升打包性能
(4) cheap-module-inline-source-map(module)
1 不仅映射业务代码和打包后的js代码,还映射loader、第三方模块的代码和打包后的js代码
(5) eval
1 打包速度最快的方式,执行效率最快,性能最好的方式
2 但是如果比较复杂的代码,提示的可能并不全面。
六 webpack之WebpackDevServer-提升开发效率
1. webpack-dev-server的安装
npm install webpack-dev-server@3.1.10 -D
webpack-dev-server运行的时候并不会生成dist文件夹。而是把生成的文件保存在内存中,从而提升打包速度。
七 webpack之Hot Module Replacement模块热更新
webpack-dev-server运行的时候并不会生成dist文件夹。而是把生成的文件保存在内存中,从而提升打包速度。
1. 开启Hot Module Replacement
【webpack官方文档查看:HMR、模块热替换】
页面代码修改不会重新刷新整个页面,只刷新代码修改的部分。
八 webpack之Tree Shaking
1. Tree Shaking的作用
只打包需要用到的模块,用不到的模块不作打包。
export const add (a, b) {
console.log(a + b)
}
export const minus (a, b) {
console.log(a - b)
}
import { add } from './utils.js'
add(1,2)
Tree Shaking只支持ES Module的引入方式。不支持CommonJS。
原因:
1 import这种ES Module的引入方式底层是静态的引入方式
2 CommonJS是一种动态的引入方式。
// webpack.config.js
optimization: { // development环境下.production环境下不需要
usedExports: true
}
// package.json
{
"name": "lesson",
"sideEffects": false, // 没有不需要tree shaking的文件
"scripts": {}
}