文章目录
1,webpack概念
什么是webpack
-
Webpack 前端资源模块化管理和打包工具。可以将许多松散的模块按照依赖和引用关系打包成符合生产环境部署的前端资源。并将按需加载的模块进行代码分隔,等到实际需要的时候再加载。
-
webpack 运行在node环境上的一个包;webpack 可以把前端的任何资源, 当做模块, 来进行打包整合, 也可以支持不同的代码(ES6模块代码, CSS文件, LESS文件, 图片…) 编写前端代码后, 可以被webpack打包整合, 运行在浏览器上;
2,为什么学webpack
- 开发的时候需要一个开发环境,要是我们修改一下代码保存之后浏览器就自动展现最新的代码那就好了;
- 本地写代码的时候,要是调后端的接口不跨域就好了(代理服务);
- 为了跟上时代,要是能用上什么ES6 等新东西就好了(翻译服务);
- 项目要上线了,要是能一键压缩代码啊图片什么的就好了(压缩打包服务);
3,webpack特点
- 丰富的插件,流行的插件, 方便进行开发工作;
- 大量的加载器,便于处理和加载各种静态资源;
- 将按需加载的模块进行代码分隔,等到实际需要的时候再异步加载;
4,相对于其他工具优点
相对于其他模块打包工具(Grant/Gulp)优势,
- Webpack 以 CommonJS 的形式来书写脚本,对 AMD / CMD / ES6 模块 的支持也很全面,方便旧项目进行代码迁移。所有资源都能模块化;
- 开发便捷,能替代 Grunt / Gulp 的工作,比如打包js/css、打包压缩图片、CSS分离, 代码压缩等。扩展性强,插件机制完善,支持模块热替换等;
5,准备工作
1,安装node和npm
node是nodejs运行的环境, npm是安装node一起安装的包管理器的工具, 可以方便的管理我们需要的所有第三方依赖包
2,安装webpack模块
webpack通常使用npm包管理工具进行安装。现在webpack对外公布的稳定版本是webpack4;
全局安装webpack命令:npm install webpack -g
命令 | 安装环境 | 备注 |
---|---|---|
npm view webpack versions --json | 不安装, 查看 | 查看现在所有webpack模块的版本号 |
npm install webpack -g | -g 全局安装 | 在全局安装webpack 在电脑就可以使用webpack命令了(工具类模块要全局) |
webpack -v | 不安装, 查看全局webpack版本号(注意, webpack4.x版本, 还要安装webpack-cli工具才可以运行此命令) | 可能出现的问题: 1. webpack不是内部或外部命令(证明你全局安装失败/计算机的环境变量node的配置失效) |
3,安装webpack-cli工具包
webpack的命令, 大多都会执行webpack-cli里的Api方法, 来实现具体的功能效果, 所以webpack4.x版本需要在全局安装此模块, 而webpack3.x没有抽离出来那些API方法, 所以webpack3.x则不需要安装此模块;
命令: npm i webpack-cli -g
注意webpack4 配合 webpack-cli3.x版本
4,两种环境讲解
- 本地开发环境(development): 我们在本地写代码的时候;
- 线上发布环境(production): 我们在本地开发完代码, 进行打包后, 对外的环境;
6,webpack的核心介绍
1,重点说明:webpack.config.js文件
Webpack为开发者提供了程序打包的配置信息入口,让开发者可以更好的控制, 管理程序的打包过程与最后程序的输出结果。默认的webpack配置文件是webpack.config.js, 运行webpack打包命令, 会自动查看运行命令时, 所在目录下的webpack.config.js文件;
注意: webpack4.x版本可以省略这个文件, webpack3.x版本是必须声明此文件的
2,核心概念讲解
官网链接: https://www.webpackjs.com/concepts/
webpack的概念名 | 解释 |
---|---|
入口起点 | 基础目录, 指定了"./src"目录, 那么下面所有的配置中使用的相对路径, 都是以src为起点 |
入口 | 入口起点指示 webpack 应该使用哪个模块来作为构建其内部依赖图的开始 进入起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的 |
出口 | output告诉 webpack 在哪输出它所创建的结果及如何命名文件,默认值为 ./dist |
加载器 | loader 让 webpack 能去处理非 JavaScript 文件(webpack 自身只理解 JavaScript)loader 可以将所有类型的文件转换为webpack 能够处理的有效模块 然后你就可以利用 webpack 的打包能力,对它们进行处理。 |
插件 | loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。 插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。 插件接口功能极其强大,可以用来处理各种各样的任务。 |
模式 | 通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化 |
3,配置文件参数讲解
官网链接: https://www.webpackjs.com/configuration/
键名 | 概念 | 解释 |
---|---|---|
context | 入口起点 | 基础目录,绝对路径,用于从配置中解析入口起点(entry point) |
entry | 入口 (必须) | 配置打包入口文件的名字 |
output | 出口 (必须) | 打包后输出到哪里, 和输出的文件名 |
module | 加载器配置 | 在rules对应数组中, 定义对象规则 |
plugins | 插件配置 | 配置插件功能 |
mode | 模式 | 选择线上/线下环境模式 |
devtool | 开发工具 | 如何生成 source map, 记录代码所在文件的行数 (调试方式) |
7,webpack使用 - 打包js代码
1,打包js代码
- 准备前端模块js文件, 和主入口文件main.js(名字自定义), 在主入口文件里使用前端封装的模块
- 在当前工程目录中声明webpack.config.js的 webpack配置文件, 并且填入配置对象信息(入口+出口必须的)
- dist不存在会自动创建
- output.path的值必须是绝对路径 (因为webpack是从全局开始创建dist目录, 所以必须从全局出发)
- 在当前工程目录中执行webpack打包命令, 查看出口生成的打包后的js文件
- 自己新建index.html文件引入打包后的js, 执行查看效果
webpack命令会自动查找当前命令所在目录下的 webpack.config.js 配置文件, 根据配置文件进行代码的打包
2,单入口–单出口
- 单个入口, 可以引入很多个要使用的模块部分, 单入口(指的是打包时候指定的入口文件)
- 单个出口, 指的打包所有js, 最后要输入到一个单独的.js文件当中使用
module.exports = {
context: __dirname + "/src", // 拼接src的绝对路径, context设置入口的文件前缀, 代表入口要从这个文件夹开始寻找 (必须是绝对路径) __dirname: 指的当前文件所在文件夹的路径路径
entry: "./main.js",
output: {
path: __dirname + '/dist', // 给我输出到同级下的dist目录中(如果没有会自动创建)
filename: 'bundle.js' // 输出js文件的名字
}
};
3,多入口–单出口
1,多入口: 告诉webpack, 去哪些文件里进行打包
module.exports = {
context: path.resolve(__dirname, "src"),
entry: ["./main.js", "./center.js"], // 设置多入口文件路径
output: {
path: __dirname + '/dist',
filename: 'bundle.js'
}
};
4,多入口–多出口
module.exports = {
context: path.resolve(__dirname, "src"),
entry: {
"first": "./main.js",
"second": "./center.js"
}, // 如果是多入口单出口用数组结构, 如果是多入口, 多出口用对象结构, 而且key值是打包后的文件名
output: {
path: __dirname + '/dist',
filename: '[name].js' // [name]是webpack内置的字符串变量, 对应entry里每个key
}
}
8,打包css代码
- 需要下载2个加载器模块 (目的是为了让webpack认识css文件)
- css-loader: 接收一个css文件, 并且解析import方式 下载cssloader的时候 降低一个版本 @3 下载的版本是3.6
- style-loader: 接收css代码, 并且将其注入到html网页中的
- 在webpack.config.js中, 加载器配置:
module: { // 对加载器进行配置
rules: [ // 加载器的使用规则
{ // 独立的规则对象
test: /\.css$/, // 以.css结尾的文件类型
use: [ 'style-loader', 'css-loader' ] // 使用哪些加载器进行转换
// 注意: 2个加载器的顺序, 默认是从右往左进行使用
}
]
}
- 在入口文件引入css模块
import "./style/home.css" // 注意无需用变量接收
-
会把css代码以字符串的形式, 打包进js文件当中
-
在dist下新建index.html, 只要引入打包后的bundle.js, 来查看css代码被打包进js的效果即可
9,生成html文件
- 需要下载1个插件模块
- html-webpack-plugin:
HtmlWebpackPlugin
简化了HTML文件的创建,你可以让插件为你生成一个HTML文件,使用默认模板, 或使用你自己指定的模板
- html-webpack-plugin:
- webpack.config.js插件配置
const HtmlWebpackPlugin = require("html-webpack-plugin");
plugins: [ // 配置各种插件
new HtmlWebpackPlugin({ // 插件配置对象
title: "webpack ldx使用",
filename: "index.html", // 产出文件名(在dist目录查看)
template: __dirname + "/index.html", // 以此文件来作为基准(注意绝对路径, 因为此文件不在src下)
inject: true, // 代表打包后的资源都引入到html的什么位置
favicon: "./assets/favicon.ico", // 插入打包后的favicon图标
// base: "./", // html网页中所有相对路径的前缀 (一般不给/给./, 虚拟路径)
// 控制html文件是否要压缩(true压缩, false不压缩)
minify: { //对html文件进行压缩,
collapseBooleanAttributes: true, //是否简写boolean格式的属性如:disabled="disabled"简写为disabled
collapseWhitespace: true, //是否去除空格,默认false
minifyCSS: true, //是否压缩html里的css(使用clean-css进行的压缩) 默认值false
minifyJS: true, //是否压缩html里的js(使用uglify-js进行的压缩)
removeAttributeQuotes: true, //是否移除属性的引号 默认false
removeComments: true, //是否移除注释 默认false
removeCommentsFromCDATA: true, //从脚本和样式删除的注释, 默认false
useShortDoctype: true //使用短的文档类型,将文档转化成html5,默认false
}
}) // 数组元素是插件new对象
]
- src/index.html 静态网页模板
- 执行webpack打包命令, 观察在dist生成的目录中, 是否新增了xxx.html文件, 并且会自动引入所有需要的外部资源
报错
Cannot find module “webpack/lib/node/NodeTeplatePlugins”
在安装html-webpack-plugin插件的工程中, 单独的在本地安装一下跟全局webpack对应的版本
插件配置项如下:
选项key | 值类型 | 默认值 | 解释 |
---|---|---|---|
title | String | Webpack App | 在生成html网页中 |
filename | String | index.html | 生成的html网页文件的名字 (也可以设置目录+名字) |
template | String | 以哪个现有的html文件作为基础模板, 在此模板的基础上, 生成html网页文件 | |
inject | Boolean/String | true | 值的范围(true || ‘head’ || ‘body’ || false) true/‘body’ -> script等引入代码, 放到body标签内部末尾 ‘head’/false -> script等引入代码, 放到head标签内部末尾 |
favicon | String | 将制定favicon.ico图标的路径, 插入到html网页中去 | |
base | String | 制定html中所有相对路径, 都以它的值为出发起点, 例如: base的值为/bar/, 那么你HTML网页里的img, src=“my.img”, 那实际上去找的路径其实是 /bar/my.img | |
minify | Boolean | 看mode的值 | 是否压缩html代码, 如果mode为’production’, 那么minify的值为true, 否则为false |
10,分离css代码
-
需要引入1个插件模块,
- extract-text-webpack-plugin 使用下一个版本@next 会将所有的入口中引用的
*.css
,移动到独立分离的CSS文件。因此,你的样式将不再内嵌到JS中,而是会放到一个单独的CSS文件中。如果你的样式文件较大,这会做更快加载,因为CSS会跟JS 并行加载。 - 此插件没有压缩css代码的功能
- extract-text-webpack-plugin 使用下一个版本@next 会将所有的入口中引用的
-
webpack.config.js加载器修改
const ExtractTextPlugin = require("extract-text-webpack-plugin");
rules: [ // 加载器的使用规则
{
test: /\.css$/,
use: ExtractTextPlugin.extract({ // 从一个已存在的 loader 中,创建一个提取(extract) loader。
fallback: "style-loader", // 应用于当CSS没有被提取(正常使用use:css-loader进行提取, 如果失败, 则使用fallback来提取)
use: "css-loader" // loader被用于将资源转换成一个CSS单独文件
})
}
]
-
插件配置: 其他选项默认即可
new ExtractTextPlugin("style.css"), // 输出的文件名
-
在dist打包生成的目录中, 就会分离出单独的.css文件
报错
Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
“extract-text-webpack-plugin”: “^3.0.2” 此插件3.x版本对应webpack3.x, 所以我们需要更高的extract版本, 所以下载extract-text-webpack-plugin@next (@next下载下一个内测最新版)
11,打包less
-
需要安装less 和 less-loader 来解析less代码, 和加载less文件
npm install less
npm install less-loader
-
在webpack.config.js中 配置加载器, 解析.less文件
{ test: /\.less$/, use: ['style-loader', 'css-loader', "less-loader"] }
-
但是这样发现css代码没有分离出来, 所以还需要使用extract-text-webpack-plugin的配置, 分离出css代码
{ test: /\.less$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ['css-loader', "less-loader"] }) }
-
观察打包后style.css中多了less文件里的样式代码
12,集成postcss
1,什么是postcss
是一个转换 CSS 代码的工具和插件 (postcss转换css代码, 为了兼容不同的浏览器)
类似于babel.js把浏览器不兼容的js转换成兼容的js代码 (babel转换js代码, 为了兼容不同浏览器)
注意它本身是一个工具, 和less/sass等预处理器不同, 它不能处理css代码
而是靠各种插件来支持css在不同浏览器和环境下正确运行的
- 增加可读性, 会自动帮你添加特定浏览器厂商的前缀 (插件: autoprefixer)
- px单位自动转rem (插件: postcss-pxtorem)
- 先下载postcss-loader 和postcss到当前工程中
npm install postcss
npm install postcss-loader@3
- postcss: 集成这个工具, 可以让它发挥它集成的翻译css的插件
- postcss-loader: 对css文件进行处理
- 新建webpack.config.js同级的postcss.config.js 配置文件
- 去webpack.config.js中, 把postcss使用到css相关的加载器中
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [{
loader: 'css-loader',
options: { importLoaders: 1 }
}, "postcss-loader"]
})
// importLoaders 用于配置「css-loader 作用于 @import 的资源之前」有多少个 loader。
},
2,autoprefixer
在css和less文件中, 准备一些代码
自动补全前缀:
1.先下载此插件模块: npm i autoprefixer@9
2.postcss.config.js 配置如下:
module.exports = {
plugins: { // postcss在翻译css代码的时候, 需要使用哪些插件功能
// 1. 写使用插件模块的名字, postcss会自己去require引入
// 2. 必须配置浏览器列表才可以 自动添加前缀
'autoprefixer': {
// 浏览器支持列表放到了package.json中browserslist中进行编写
}
}
}
package.json的browserslist下设置
"browserslist": [
"defaults",
"not ie < 11",
"last 2 versions",
"iOS 7",
"last 3 iOS versions"
]
// defaults相当于 "> 5%", 国内浏览器使用率大于5%的
// not ie < 11 不兼容IE11以下的浏览器 (支持ie11)
// 支持最后2个版本
// iOS苹果手机操作系统, 支持ios7
// 支持最后3个IOS的版本 ios13, 12, 11
- 打包观察生成的style.css文件中代码是否拥有浏览器兼容的前缀
3,postcss-pxtorem
浏览 && 画图, 解释rem 如何适配的
此插件是自动把(css/less…文件里 px转换成适配的rem单位), 无需再手动计算了
- 先下载此插件模块 npm i postcss-pxtorem
- 在postcss.config.js中配置如下,
'postcss-pxtorem': {
rootValue: 16, // 这个值就是你看设计稿上基准字体是多少, 就写多少, 1rem=16px
unitPrecision: 6, // 小数点几位
propList: ['*'], // 指定需要转换rem的属性 例如: 'font-size' 'line-height' *代表所有属性
mediaQuery: false, // 媒体查询的px是否转换
minPixelValue: 0, // 小于指定数值不转换
// 默认px识别大写小, 所以不写成px不转换
}
注意: 只对css/less文件内代码有效, 因为webpack.config.js中, 加载器使用了postcss-loader
注意: 如果html中使用px转rem, 可以安装插件, 来自动把px转换成rem使用
注意: html的font-size不会自动随着网页的变化而变化
- 在index.html模板文件中, 根据当前网页设置html的fontSize, 来让所有rem单位在运行时得到真正的像素大小
13,压缩css文件
想要压缩打包后的css文件, 可以使用 optimize-css-assets-webpack-plugin, 先下载这个插件,在webpack.config.js中配置
const OptimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [ // 新增
new OptimizeCss()
]
14,打包_assets
- 需要引入2个加载器模块,
- url-loader:
url-loader
功能类似于file-loader
,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL(base64字符串) - file-loader: 产出, 寻找文件的引用位置
- url-loader:
- 准备工作: 注意打包的资源, 都要和入口文件产生直接/间接关系, 所以不要写在index.html模板文件中, 那样是不会被webpack处理的
- assets 下准备 图片 和字体图标
- 在main.js中, 创建标签, 使用图片/字体图标样式
注意: webpack认为, 图片也是一个模块, 所以才需要loader来解析图片, 所以图片需要import/require引入)
- webpack.config.js加载器配置:
/*{
test: /\.(png|jpg|jpeg|gif|svg)$/,
use: [
{
loader: 'url-loader',
options: { // 参数
limit: 8192 // 8kb内的文件都转换成DataURL, 如果超出的都转换成base64字符串
}
}
]
},
*/
// 上面options可以简写成下面?传参数的格式
{
test: /\.(png|jpg|jpeg|gif|svg)$/, // 处理这些结尾的文件
use: [
{ // options传参的方式被我改成了?传参
// ? 代表给加载器传入配置参数
// limit字段: 对打包的图片限制字节大小为8KB以内, 超出此限制,会被file-loader产生一个文件
// [name]: 代表直接使用打包目标文件的名字,
// [ext]: 代表直接使用打包目标文件的扩展名
// name字段: 代表给打包后的文件定义名字(可以使用[]这种规则)
// 8KB
loader: 'url-loader?limit=8192&name=assetsDir/[name].[ext]'
}
]
}
// 如果处理字体图标需要引入这个
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name].[hash:7].[ext]'
}
}
- 执行打包命令, 查看dist目录中和index.html中的效果
总结: 小于limit限制的assets下的图片资源, 都会被打包进js文件中, 先被url-loader转换成了base64字符串 (这种加密方式的字符串, 可以被img标签的src所接受, 但是一定要在base64加密的字符串前, 声明一个表示 data:image/png;base64, 后面跟base64字符串)
15.使用总结
找插件/加载器, 下载插件/加载器模块, webpack.config.js中进行配置, 编码/准备资源, 打包, 把打包后的资源部署到服务器上;
部署: 配置环境和需要的各种软件参数等, 上传代码资源包
16,node常用的方法/变量
-
__dirname (注意2个下划线): 代表当前文件所在文件夹的 绝对路径
-
path.resolve: 合并2个路径
17,webpack的作用是什么,谈谈你对它的理解
答案
: 现在的前端网页功能丰富,特别是SPA(single page web application 单页应用)技术流行后,JavaScript的复杂度增加和需要一大堆依赖包,还需要解决SCSS,Le…新增样式的扩展写法的编译工作。所以现代化的前端已经完全依赖于WebPack的辅助了。
现在最流行的三个前端框架,可以说和webpack已经紧密相连,框架官方都推出了和自身框架依赖的webpack构建工具。
· React.js+WebPack
· Vue.js+WebPack
· AngluarJS+WebPack
webpack的工作原理?
答案:
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。在3.0出现后,Webpack还肩负起了优化项目的责任。
webpack插件网址
https://www.webpackjs.com/plugins/
webpack加载器网址
https://www.webpackjs.com/loaders/