前端工程化解决方案之Webpack
学习目标:
◆ 能够说出什么是前端工程化
◆ 能够说出 webpack 的作用
◆ 能够掌握 webpack 的基本使用
◆ 了解常用 plugin 的基本使用(插件)
◆ 了解常用 loader 的基本使用(处理兼容性)
◆ 能够说出 Source Map 的作用(浏览器排错)
1. 什么是webpack?
- 概念: webpack 是基于 node.js 开发出来的前端项目工程化的具体解决方案。
- 主要功能: 它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端 JavaScript 的兼容性、性能优化等强大的功能。
- 好处: 让程序员把工作的重心放到具体功能的实现上,提高了前端开发效率和项目的可维护性。
- 注意: 目前 Vue,React 等前端项目,基本上都是基于 webpack 进行工程化开发的。
2. 实际开发中:
- Vue项目中,使用 Vue-cli 一键生成带有 webpack 的项目。
- 开箱即用,所有 webpack 配置项都是现成的!
- 我们只需要知道 webpack 中的基本概念即可!
从一个小项目开始讲解【本文用到的命令,以及插件的版本可以自行参考相应的官方文档】
1. 初始化包管理配置文件package.json
- 新建项目空白目录下运行如下命令,即初始化包管理配置文件 package.json
npm init –y
- 新建 src 源代码目录。(这个目录是放程序员的源代码的)
- 新建 src -> index.html 首页和 src -> index.js 脚本文件
- 初始化首页基本的结构
- 运行如下命令,安装 jQuery
npm install jquery –S
- index.js 通过 ES6 模块化的方式导入 jQuery
import $ from 'jquery'
发现,语法不兼容,这时候我们就需要用webpack来解决了。安装 webpack 相关的两个包。
2. 安装 webpack
(注:安装失败的话尝试用管理员身份安装 sudo npm i webpack )
npm install webpack@5.42.1 webpack-cli@4.7.2 -D
但是,只安装不配置是不行的。
3. 配置 webpack
- 在项目根目录中,创建名为 webpack.config.js 的 webpack 配置文件,并初始化如下的基本配置:
// 对外暴露exports对象,添加mode对象成员 module.exports = { mode: 'development' } // mode 代表 webpack 运行的模式,可选值有两个 development 和 production // 结论:开发用 development,追求的是打包的速度,而不是体积; // 反过来,发布上线用 production,上线追求体积小,而不是打包速度快!
- 在 package.json 的 scripts 节点下,新增 dev 脚本如下:
"scripts": { "dev": "webpack", // 代表运行 npm run dev 可以启动 webpack 打包 }
这时候,运行 npm run dev 就可以打包 js 文件了,此时,index.html 引入的 js 文件应该改成打包后的js文件!
4. 修改打包入口和输出路径
在 webpack 4.x 和 5.x 的版本中,有如下的默认约定:
- 默认的打包入口文件为 src -> index.js
- 默认的输出文件路径为 dist -> main.js
但是,打包入口文件和输出文件是可以在 webpack.config.js 中修改的,修改配置如下:
//记得先导入 path 模块 const path = require('path') //在暴露对象中增加 module.exports = { // entry: '指定要处理哪个文件' entry: path.join(__dirname, './src/index1.js'), // 指定生成的文件要存放到哪里 output: { // 想要存放的目录 path: path.join(__dirname, 'dist'), // 想要生成的文件名 filename: 'js/bundle.js' }
6. 安装 webpack 插件
在上面的修改代码过程中,需要频繁运行 npm run dev 重启 webpack 打包,这时候我们需要安装一下插件来实现自动监听代码修改,从而自动重启 webpack 打包了(类似于 node.js 中的 nodemon)
npm install webpack-dev-server@3.11.2 -D
需要配置:
- 修改 package.json -> scripts 中的 dev 命令如下:
"scripts" : { "dev" : "webpack serve" , // 运行 npm run dev }
- 此时,再次运行
npm run dev
,可以启动一个实时打包的 htpp 服务器,在浏览器中访问 http://localhost:8080 地址,查看自动打包效果
这时候,在文件中是看不到打包后的js文件的,因为配置了 webpack-dev-server ,打包文件存在内存中了,而且是虚拟的,而不是物理磁盘。此时,可以直接用 / 表示项目根目录,后面跟上要访问的文件名称,即可访问内存中的文件,如 /index.js (此时,index.html也应该改为引入这个路径下的js文件了)
7. 安装 webpack 插件
到这里,我们可以通过访问 http://localhost:8080 查看开发页面,但是,每次点进去只看到文件目录文件夹,需要点击src文件夹才能访问页面,所以这时候就需要通过 html-webpack-plugin 这个插件复制一份 index.html镜像文件 到项目根目录了。
npm install html-webpack-plugin@5.3.2 -D
需要配置 webpack.config.js :
// 1. 导入 html-webpack-plugin 这个插件,得到插件的构造函数 const HtmlPlugin = require('html-webpack-plugin') // 2. new 构造函数,创建插件的实例对象 const htmlPlugin = new HtmlPlugin({ // 指定要复制哪个页面 template: './src/index.html', // 指定复制出来的文件名和存放路径 filename: './index.html' }) // 在这里增加 plugins节点 配置 htmlPlugin 插件,使插件生效 module.exports = { //插件的数组,将来 webpack 在运行时,会加载并调用这些插件 plugins: [htmlPlugin] //其实只有一个插件的时候可以不写数组形式 }
注:复制出来的inde.html也是看不见的,虚拟的,放在内存中的。
在 webpack.config.js 配置文件中,可以通过在 module.exports 中添加 devServer 节点对 webpack-dev-server 插件进行更多的配置,如下:
devServer: { // 首次打包成功后,自动打开浏览器 open: true, // 在 http 协议中,如果端口号是 80,则可以被省略 port: 80, // 指定运行的主机地址 host: '127.0.0.1' }
注意:凡是修改了 配置文件,必须重启实时打包的服务器,否则最新的配置文件无法生效!
npm run dev
8. 安装louder插件
在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块,webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错!
loader 加载器的作用:协助 webpack 打包处理特定的文件模块。比如:
- css-loader 可以打包处理 .css 相关的文件
- less-loader 可以打包处理 .less 相关的文件
- babel-loader 可以打包处理 webpack 无法处理的高级 JS 语法
安装处理CSS文件的loader:
npm i style-loader@3.0.0 css-loader@5.2.6 -D
安装处理less文件的loader:
npm i less -loader@10.0.1 less @4.1.1 -D
安装处理JS与打包处理样式表中与url路径相关的的loader:
npm i url-loader@4.1.1 file -loader@6.2.0 -D
以上三个loader的配置:在 webpack.config.js 的 exports 下的 module -> rules 数组中,添加 loader 规则如下:
module: { rules: [ // 定义了不同模块对应的 loader 参数顺序必须按照下面 { test: /\.css$/, use: ['style-loader', 'css-loader'] }, // 处理 .less 文件的 loader { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, // 处理图片文件的 loader // 如果需要调用的 loader 只有一个,则只传递一个字符串也行,如果有多个loader,则必须指定数组 // 在配置 url-loader 的时候,多个参数之间,使用 & 符号进行分隔,这里顺便把打包的图片文件也指定了输出路径了,这里意思是小于470byte的图片文件才转为base64格式,否则加载原图片
{ test: /\.jpg|png|gif$/, use: 'url-loader?limit=470&outputPath=images' }, // 使用 babel-loader 处理高级的 JS 语法 // 在配置 babel-loader 的时候,程序员只需要把自己的代码进行转换即可;一定要排除 node_modules 目录中的 JS 文件 // 因为第三方包中的 JS 兼容性,不需要程序员关心 { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ } ] }
安装处理JS高级语法的loader:
npm i babel-loader@8.2.2 @babel/core@7.14.6 @babel/plugin-proposal-decorators@7.14.5 -D
配置:在项目根目录下,创建名为 babel.config.js 的配置文件,定义 Babel 的配置项如下:
module.exports = { // 声明 babel 可用的插件 // 将来,webpack 在调用 babel-loader 的时候,会先加载 plugins 插件来使用 plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]] }
9. 项目打包发布配置
项目开发完成之后,需要使用 webpack 对项目进行打包发布,主要原因有以下两点:
- 开发环境下,打包生成的文件存放于内存中,无法获取到最终打包生成的文件
- 开发环境下,打包生成的文件不会进行代码压缩和性能优化
为了让项目能够在生产环境中高性能的运行,因此需要对项目进行打包发布。
因此,在 package.json 文件的 scripts 节点下,新增 build 命令如下:
"scripts": { "dev": "webpack serve", //项目开发用的命令 "build": "webpack --mode production" //项目发布打包运行 npm run build 命令 }
注意:通过 --model 指定的参数项,会覆盖 webpack.config.js 中的 model 选项,也就是覆盖开发模式选项。
10. 模块化存放输出文件配置
但是呢,dist 文件内的各类文件最好模块化分类存放啦,这就需要一下配置了:
指定生成的 js 文件放在哪里,上面已经讲过了,在 webpack.config.js 配置文件的 output 节点中,进行如下配置:
// 指定生成的文件要存放到哪里 output: { // 存放的目录 path: path.join(__dirname, 'dist'), // 生成的文件名 filename: 'js/bundle.js' }
指定生成的图片文件放在哪:上面提示了。
11. 安装自动清理dist旧文件的插件
为了在每次打包发布时自动清理掉 dist 目录中的旧文件,可以安装并配置 clean-webpack-plugin 插件:
// 1、安装清理 dist 目录的webpack插件
npm i clean-webpack-plugin@3.0.0 -D
// 2.按需导入插件、得到插件的构造函数之后,创建插件的实例对象
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const cleanPlugin = new cleanWebpackPlugin()
// 3. 把创建的 cleanPlugin 插件实例对象,挂载到 plugins 节点中
plugins: [htmlPlugin,cleanPlugin],// 挂载插件
12. 了解Source Map
前端项目在投入生产环境之前,都需要对 JavaScript 源代码进行压缩混淆,从而减小文件的体积,提高文件的 加载效率。此时就不可避免的产生了另一个问题:对压缩混淆之后的代码除错(debug)是一件极其困难的事情,这时候就要认识一下 Source Map 了
在开发环境下,webpack 默认启用了 Source Map 功能。当程序运行出错时,可以直接在控制台提示错误行的位置,并定位到具体的源代码。但是,
记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行 数不一致的问题。
解决默认Source Map问题:
开发环境下,推荐在 webpack.config.js 中添加如下的配置,即可保证运行时报错的行数与源代码的行数保持一致:
module.exports = {
mode: 'development',
// eval-source-map 仅限在"开发模式"下使用,不建议在“生产模式”下使用。
// 此选项生成的 Source Map能够保证"运行时报错的行数"与"源代码的行数"保持一致
devtool:'eval-source-map',
// 省略其它配置项...
}
13. @根路径配置
路径问题,用@代表根目录配置 webpack.config.js:
module.exports = {
resolve:{
alias:{
@:path.join(__dirname,'./src')
}
}
}
14. 打包发布省略Source Map
在生产环境下,如果省略了 devtool 选项,则最终生成的文件中不包含 Source Map。这能够防止原始代码通 过 Source Map 的形式暴露给别有所图之人。
- 开发环境下:
建议把 devtool 的值设置为 eval-source-map
好处:可以精准定位到具体的错误行 - 生产环境下:
建议关闭 Source Map 或将 devtool 的值设置为 nosources-source-map
好处:防止源码泄露,提高网站的安全性
本文来自博客园,作者:RHCHIK,转载请注明原文链接:https://www.cnblogs.com/suihung/p/16119128.html