Webpack的安装和介绍
1.1 Webpack是什么
webpack是现代前端开发中最火的模块打包工具,只需要通过简单的配置,便可以完成模块的加载和打包。
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
- 为什么要使用Webpack
- 模块化开发(import,require)
- 预处理(Less,Sass,ES6,TypeScript……)
- 主流框架脚手架支持(Vue,React,Angular)
- 庞大的社区(资源丰富,降低学习成本)
- webpack 不仅能处理 js, 也能处理 css, 还能处理 html,甚至是图片等各种前端资源;
- 开发便捷,仅仅使用一个配置文件,就能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转 base64等;
- 扩展性强,插件机制完善。
1.2 webpack核心概念
- Entry : 输入入口,webpack构建第一步从这里开始
- Moudle :一个模块对应一个文件,从entry 开始递归找到所有依赖的模块
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割
- Loader:模块转换器,将模块原内容按照需求转换成新内容
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情
- Output:输出,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果
//webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin'); //分离CSS和JS文件
const CleanWebpackPlugin = require('clean-webpack-plugin'); //去除build文件中的残余文件
const path = require('path');
const webpack=require('webpack');
let pathsToClean = [
'dist'
]
module.exports = {
entry: {
//唯一入口文件
"app.bundle": "./src/app.js",
"contact": "./src/contact.js"
},
devServer: {
//配置本地服务器
port: 8686, //端口号
open: true, //设置是否自动打开
hot:true //模块热替换,热更新
//inline:true //实时刷新
},
output: {
//输出文件
path: path.resolve(__dirname, 'dist'), //打包后的文件存放的地方
filename: '[name].[hash].js' //打包后输出文件的文件名
},
plugins: [
new HtmlWebpackPlugin({
//new 一个插件的实例,并传入相关的参数
// title:'hello world' //自动添加HTML的标题
template: './src/index.html',
filename: 'index.html',
minify: {
collapseWhitespace: true
},
hash: true,
//excludeChunks代表的不包含
excludeChunks: ['contact']
}),
new HtmlWebpackPlugin({
template: './src/contact.html',
filename: 'contact.html',
minify: {
collapseWhitespace: true
},
hash: true,
//chunks代表的是包含
chunks: ['contact']
}),
new CleanWebpackPlugin(pathsToClean),
new ExtractTextPlugin({
filename:'style.css',
disable:true
}),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin() //自动刷新实时预览修改后的效果
//new webpack.optimize.UglifyJsPlugin() //压缩JS代码
],
module: {
rules: [
{
test: /\.css$/, //用以匹配loaders所处理文件的拓展名的正则表达式
use: ['style-loader','css-loader','postcss-loader'] //style-loader要配置在css-loader之前
}
]
}
}
entry 对象是用于 webpack 查找启动并构建 bundle。其上下文是入口文件所处的目录的绝对路径的字符串。
注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
1.3 Webpack的安装
在安装 Webpack 前,本地需要安装nodejs运行环境,下载地址:node,根据你的系统下载版本。
[外链图片转存失败(img-XlB4nGjM-1568858497838)(E:\Typora\笔记地址\markdown\img\webpackImg\node.webp)]
下载安装包后,点击可执行文件,不断地按下一步,就可以安装成功。测试安装是否成功,使用 node -v
,如果显示版本号则表示安装成功。
[外链图片转存失败(img-vFtHVEyv-1568858497840)(E:\Typora\笔记地址\markdown\img\webpackImg\node-v.webp)]
1.3.1 全局安装(不推荐)
在命令行上输入以下命令:npm install -g webpack
,测试是否安装成功输入 webpack -v
,如果显示版本号则安装成功。
超过4.0安装方式
npm i -D webpack
i 是 install 的缩写
npm i -D webpack-cli
命令行的使用
#### 命令解释
-S:--save
的简写,等同于npm run start 只需输入npm start,这两个效果是一样的。
-D:--save-dev
的简写,其包名称及版本号会存在package.json的devDependencies这个里面,而–save则会将包名称及版本号放在dependencies里面。
npm 是 nodejs 管理插件用的工具,install 表示安装,-g 时 gobal 的缩写 表示全局安装。
也可以使用 cnpm, 但是在此之前 需要执行以下命令
npm install -g cnpm --registry=https://registry.npm.taobao.org
[外链图片转存失败(img-xDIjPqlr-1568858497840)(E:\Typora\笔记地址\markdown\img\webpackImg\webpack-v.webp)]
1.3.2 初始化项目文件
在任意盘符新建一个文件夹,如在D盘创建webpackDemo文件夹;
之后你会看到提示输入一些内容,这不用管,直接全部回车。
如果不想输入 信息 可以加 -y 代表 yes
npm init -y
创建完成之后,会发现 webpack-test目录下多出了一个名为 package.json 的文件,主要是显示这个项目的名称、版本、作者、协议等信息。
{
"name": "webpack-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.11.0"
}
}
1.3.3 在项目中安装webpack
在命令行中输入
npm install --save-dev webpack
[外链图片转存失败(img-r4FiAjNH-1568858497841)(E:\Typora\笔记地址\markdown\img\webpackImg\npm-install.webp)]
你会看到正在安装 webpack 的进度,稍等片刻,成功之后,我们再来看看 package.json 这个文件的内容,多了下面这几行:
"devDependencies": {
"webpack": "^3.11.0"
}
同时你也会发现,多了一个目录,叫 node_modules,这就是存放刚才安装的 webpack 库所有要用到的源码文件。
如果你使用的是 npm 5,可能还会在目录中看到一个 package-lock.json 文件。
Webpack的快速使用
首先我们创建一个目录,初始化 npm,然后 在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack):
mkdir webpack-demo && cd webpack-demo
npm init -y
`npm i -D webpack`
`npm i -D webpack-cli `
项目的结构
webpack-demo
+ |- package.json
+ |- /dist
+ |- index.html
+ |- /src
+ |- index.js
-
第二步:安装 loadash 依赖和编写 js 文件
npm install --save lodash
- 编写:src/index.js 文件
import _ from 'lodash'; function createDomElement() { var dom = document.createElement('div'); dom.innerHTML = _.join(['aicoder', '.com', ' wow'], ''); return dom; } document.body.appendChild(createDomElement());
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>起步</title> </head> <body> <script src="./main.js"></script> </body> </html>
-
第三步:编写 webpack 配置文件
根目录下添加
webpack.config.js
文件。webpack-demo |- package.json + |- webpack.config.js |- /dist |- index.html |- /src |- index.js
-
webpack.config.js 内容如下:
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { filename: 'main.js', path: path.resolve(__dirname, './dist') } };
-
-
执行构建任务
- 直接执行构建任务
npx webpack
打开: dist/index.html 可以查看到页面的结果。
[外链图片转存失败(img-ofms2Wxw-1568858497842)(E:\Typora\笔记地址\markdown\img\webpackImg\newinst.png)]
2.1 加载非js文件
webpack 最出色的功能之一就是,除了 JavaScript,还可以通过 loader 引入任何其他类型的文件
在webpack的世界里,一起文件都是模块。
默认webpack只会打包js代码,想要打包其它内容,就需要相对应的loader。
不使用loader 的情况
[外链图片转存失败(img-EWhENnao-1568858497843)(E:\Typora\笔记地址\markdown\img\webpackImg\loader-error.png)]
2.1.1 加载CSS文本
- 第一步: 安装 css 和 style 模块解析的依赖
style-loader
和css-loader
npm install --save-dev style-loader css-loader
or
npm i -D style-loader css-loader
-
第二步: 添加 css 解析的 loader
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, module: { // 这个节点,用于配置 所有 第三方模块加载器 rules: [ // 所有第三方模块匹配规则 { // 加载 以 css为后缀的 文件 test: /\.css$/, // 从右向左读取loader use: ['style-loader', 'css-loader'] } ] } };
-
css-loader
: 辅助解析 js 中的import './main.css'
并将其打包 -
style-loader
: 把 js 中引入的 css 内容 注入到 html 标签中,并添加 style 标签.依赖css-loader
-
解释
打开 webpack.config.js
这个配置文件,在里面,新增一个配置节点,叫做 module,它是一个对象;在 这个 module 对象身上,有一个 rules 属性,这个 rules
属性是个 数组;这个数组中存放了所有第三方文件的配置 和处理规则;
webpack 处理第三方文件类型的过程
注:
1.发现这个 要处理的文件 不是 JS 文件,然后就去 配置文件中,查找有没有对应的第三方 loader 规则
2.如果能找到对应的规则,就会调用 对应的 loader 处理 这种文件类型
3.在调用loader 的时候,是从后往前调用的;
4.当最后的一个 loader 调用完毕,会把处理的结果,直接交给 webpack 进行打包合并,最终输出到bundle.js中去
-
第三步: 编写 css 文件和修改 js 文件
-
在 src 目录中添加
style.css
文件webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src + |- style.css |- index.js |- /node_modules
src/style.css
.hello { color: red; }
修改 js 文件
import _ from 'lodash'; + import './style.css'; function createDomElement() { let dom = document.createElement('div'); dom.innerHTML = _.join(['aicoder', '.com', ' wow'], ''); + dom.className = 'hello'; + or + dom.classList.add('box') return dom; } document.body.appendChild(createDomElement());
最后重新打开 dist 目录下的 index.html 看一下文字是否变成颜色。
[外链图片转存失败(img-EDUycR5E-1568858497844)(E:\Typora\笔记地址\markdown\img\webpackImg\webpack-lightgren.png)]
2.1.2 module 配置补充
-
模块(module): 这些选项决定了如何处理项目中的不同类型的模块。
webpack 模块可以支持如下:
- ES2015 import 语句
- CommonJS require() 语句
- AMD define 和 require 语句
- css/sass/less 文件中的 @import 语句。
- 样式
(url(...))
或 HTML 文件(<img src=...>)
中的图片链接(image url)
module.noParse
值的类型: RegExp | [RegExp] | function
防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。
module.exports = {
mode: 'devleopment',
entry: './src/index.js',
...
module: {
noParse: /jquery|lodash/,
// 从 webpack 3.0.0 开始,可以使用函数,如下所示
// noParse: function(content) {
// return /jquery|lodash/.test(content);
// }
}
...
};
npx webpack 简写
我们可以将 npx webpack 设置 到 package.json 当中 scripts处 ,重复的书写都可以如此
"build": "npx webpack -c webpack.config.js"
module.rules
创建模块时,匹配请求的规则数组。这些规则能够修改模块的创建方式。这些规则能够对模块(module)应用 loader,或者修改解析器(parser)。
module.exports = {
...
module: {
noParse: /jquery|lodash/,
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
...
};
规则 -->rules : 意思就是 满足 /.css 开头的 必须经过 use[‘style-loader’,‘css-loader’]
module.Rule
上面的每一组就是一个 rule
- Rule 条件详解
- 字符串:匹配输入必须以提供的字符串开始。是的。目录绝对路径或文件绝对路径。
- 正则表达式:test 输入值。
- 函数:调用输入的函数,必须返回一个真值(truthy value)以匹配。
- 条件数组:至少一个匹配条件。
- 对象:匹配所有属性。每个属性都有一个定义行为。
Rule.test
-
{ test: Condition }:匹配特定条件。一般是提供一个正则表达式或正则表达式的数组,但这不是强制的。
module.exports = { ... module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] } ... };
其他的条件比如:
{ include: Condition }
:匹配特定条件。一般是提供一个字符串或者字符串数组,但这不是强制的。{ exclude: Condition }
:排除特定条件。一般是提供一个字符串或字符串数组,但这不是强制的。{ and: [Condition] }
:必须匹配数组中的所有条件{ or: [Condition] }
:匹配数组中任何一个条件{ not: [Condition] }
:必须排除这个条件
module.exports = {
...
module: {
rules: [
{
test: /\.css$/,
include: [
path.resolve(__dirname, "app/styles"),
path.resolve(__dirname, "vendor/styles")
],
use: ['style-loader', 'css-loader']
}
]
}
...
};
匹配 css 并需要 包含 上面的路径
Rule.use
应用于模块指定使用一个 loader。
Loaders can be chained by passing multiple loaders, which will be applied from right to left (last to first configured).
加载器可以链式传递,从右向左进行应用到模块上。
use: [
'style-loader',
//通过json 形式
{
loader: 'css-loader'
},
// 好处是可以附加一些选项的参数
{
loader: 'less-loader',
options: {
noIeCompat: true
}
}
];
加载 Sass 文件
加载 Sass 需要sass-loader
。
安装
npm install sass-loader node-sass webpack --save-dev
or
npm i -D sass-loader node-sass
使用
// webpack.config.js
module.exports = {
module: {
rules: [{
// 加载 以 sa c sa 开头的 ss 文件
test: /\.(sc|c|sa)ss$/,
// 完整书写, (推荐简写)
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader"
}]
}]
}
};
为 sass 文件注入内容:
如果你要将 Sass 代码放在实际的入口文件(entry file)之前ÿ