前端 Webpack

Webpack,一个用于现代 JavaScript 应用程序的静态模块打包工具。

一、什么是 Webpack?

Webpack 是一个现代的 JavaScript 应用的静态模块打包工具。

Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。

二、Webpack 的安装

1. 安装 node.js

2. 安装 Webpack

(1) 安装 Webpack

1
npm install webpack@版本号 -g --save-dev
  • -g 表示全局安装
  • webpack 可以后跟 @版本号 ,用于安装指定版本,否则会安装最新版本
  • --save-dev 的含义是将安装包信息写入 package.json 文件的 devDependencies 字段中

(2) 安装 Webpack-cli

webpack4.+ 开始 webpack-cli 是必备的

1
npm install --save-dev webpack-cli

(3) 全局安装和局部安装

  • 全局安装意味着本机上所有的项目都将使用它

  • 本地安装可以让每个项目都拥有独立的包,不受全局包的影响,方便项目的移动、复制、打包等。

(4) 检查是否安装成功

在全局或本地执行

1
webpack -v

三、打包示例

如果用模块化的方式开发 js 文件,直接在 index.html 中引入时浏览器将无法识别。并且如果多个 js 文件使用不同的模块化规范,且相互依赖,在浏览器中的引入将会非常麻烦。

此时便可以使用 webpack 工具,对多个 js 文件进行打包。

1. 准备工作

(1) 目录结构

  • dist 文件夹,用于存放打包后的文件
  • src 文件夹,用于存放源文件
  • index.html 首页文件

(2) Webpack 版本

局部安装 Webpack ,版本为 3.6.0

1
npm install webpack@3.6.0 --save-dev

2. js 文件

main.js

1
2
3
4
import {differ, sum} from "./math.js"

console.log(sum(10, 20));
console.log(differ(10, 20));

math.js

1
2
3
4
5
6
7
8
9
10
11
12
function sum(num1, num2){
return num1 + num2;
}

function differ(num1, num2) {
return num1 > num2 ? num1 - num2 : num2 - num1;
}

export {
sum,
differ,
}

3. 打包

Webpack 将会自动寻找 js 文件所依赖的其它文件,并将其打包为一个新的 js 文件。该文件拥有原文件的所有功能,无需依赖,可以独立运行,同时也能被浏览器所识别。

1
2
3
4
// 语法
webpack 文件名 打包后文件名
// 实例
webpack ./src/main.js ./dist/bundle.js

4. 使用打包后文件

直接在 HTML 文件中引用即可。

1
<script src="dist/bundle.js"></script>

四、Webpack 的配置

可以将一些编译选项放在配置文件中,以便统一管理。

1. webpack.config.js

在项目目录中创建 webpack.config.js ,在其中填入配置信息。

1
2
3
4
5
6
7
8
9
10
11
const path = require('path');

module.exports = {
// 入口
entry: "URL",
// 出口
output: {
path: path.resolve(__dirname, 'dist'),
filename: "打包后文件名.js"
}
};
  • 通过 module.exports 向外暴露内容
  • entry 为入口,其值为源文件的 URL 字符串
  • output 为出口,其值为一个对象,其中
    • path 需要填入绝对路径
    • filename 填入打包后的文件名

绝对路径的具体实现方法是:

  • 通过 require('path') 引入路径依赖包 path
  • 调用 path 的 resolve() 将相对路径转化为绝对路径。其中,__dirname 指当前文件的上一级绝对路径,将该绝对路径与 dist 文件夹名进行拼接,从而获得了执行 dist 文件夹的绝对路径

2. package.json

可以在 package.json 中对指令进行映射,具体实现方式为:

  • 打开 package.json 文件

  • 在 script 属性下的对象中添加键值对,其中 key 为快捷指令,value 为原代码

    例如:

    1
    "build": "webpack"
  • 通过这种方式执行的命令,会优先使用局部安装的 Webpack,

设置好指令映射之后,便可以使用 npm run 快捷指令 来方便地运行指令。

五、loader 的使用

1. 什么是 loader?

webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。

Webpack 本身只能处理 js 代码,但在实际开发中,往往还需要其它的处理,例如:将 ES6、typescript 转化为 ES5,将 scss、less 转化为 css,将 .jsx、.vue 转化为 js 文件等。此时就可以使用 loader 进行转化。

2. loader 使用

3. loader 样式

  • 使用 XXX-loader 将对应文件编译为 CSS

  • 使用 css-loader 加载并解析引入的 css 文件,导出 CSS 代码

  • 使用 style-loadercss-loader 导出的 CSS 代码作为样式添加到 DOM 中

4. loader 图片

  • url-loader 如果图片小于限定值(一般为 8kb),则会将图片转化为 base64,通过 DataURL 访问
  • file-loader 将文件放置到 dist 文件夹中,并修改文件引用路径及文件名(可选,hash 防止冲突)。

5. loader ES6

使用 babel-loader 将 ES6 代码转换成 ES5 。

转换前:

转换后:

六、webpack 中配置 Vue

1. 安装 Vue

1
npm install vue --save

2. 引入 Vue

1
import Vue from 'Vue';

3. 修改 Vue 版本

默认情况下,Vue 将会运行 runtime-only 版本,需要改成 runtime-compiler 版本。

在 webpack.config.js 中新增属性如下,从而实现版本的修改。

1
2
3
4
5
6
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js',
'Vue$': 'vue/dist/vue.esm.js'
}
}

4. 使用 Vue

1
2
3
const app = new Vue({
···
})

5. Vue 封装处理

(1) .vue 文件

组件以 js 的方式进行组织和使用非常麻烦,也不方便为组件设置样式,此时便可以使用 .vue 文件。通过它将组件的模板、代码、样式组织在一起。

(2) 处理 Vue 文件

通过 vue-loade 和 vue-template-compiler 实现:

1
npm install vue-loader vue-template-compiler --save-dev

在 webpack.config.js 中的 modules 关键字下进行配置

(3) 示例

APP.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<template>
<div>
<h2 class="title">数字是:{{num}}</h2>
<input type='button' value='按钮' @click="add">
<p>这些东西来自Vue文件</p>
</div>
</template>

<script>
export default {
name: 'App',
data() {
return {
num: 30,
}

},
methods: {
add() {
this.num++;
}
}
}
</script>

<style>
.title {
color: red;
}
</style>

main.js:

1
2
3
4
5
6
7
8
9
10
11
12
import Vue from 'vue'
import App from './vue/App.vue'

new Vue ({
el: '#app',
// 设置模板,并在模板中调用子组件
template: `<App></App>`,
// 注册子组件
components: {
App,
}
});

index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
// 只需要给Vue一个入口即可
<div id='app'>
</div>
</body>
<script src="dist/bundle.js"></script>
</html>

七、plugin 的使用

1. 什么是 plugin?

plugin 是插件,用于对 webpack 进行各种功能扩展,例如打包优化、文件压缩等。

2. plugin 和 loader 的区别

  • plugin:用于转换某些类型的模块,是一个转换器
  • loader:用于扩展功能,是一个扩展器

3. plugin 的使用

  • npm 安装
  • 在 webpack.config.js 中配置

4. BannerPlugin

(1) 说明

用于向打包文件中添加版权信息。

(2) 步骤

在 webpack.config.js 添加如下信息:

1
2
3
4
5
6
7
8
9
10
11
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
const webpack = require('webpack');

module.exports = {
···
plugins: [
···
new webpack.BannerPlugin('版权信息')
]
};

5. HtmlWebpackPlugin

(1) 说明

HtmlWebpackPlugin 可以自动生成一个 index.html 文件,并将打包后的 js 文件自动通过 script 插入。

(2) 步骤

  • 首先安装插件

    1
    npm install html-webpack-plugin -- save-dev
  • 修改配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    const HtmlWebpackPlugin = require('html-webpack-plugin')

    module.exports = {
    ···
    plugins: [
    ···
    new HtmlWebpackPlugin(),
    ]
    };

    配置文件处可填入参数,例如:

    1
    2
    3
    4
    5
    6
    plugins: [
    ···
    new HtmlWebpackPlugin({
    template: 'index.html'
    }),
    ]

    webpack会在目录中查找文件,并将该文件作为输出文件的模板。

6. uglifyjs-webpack-plugin

(1) 说明

用于对 js 文件进行压缩。

(2) 步骤

  • 首先安装插件

    1
    npm install uglifyjs-webpack-plugin --save-dev
  • 修改配置文件 webpack.config.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

    module.exports = {
    ···
    plugins: [
    ···
    new UglifyJsPlugin(),
    ]
    };

7. webpack-dev-server

(1) 说明

用于设置一个本地开发服务器,可以让浏览器自动刷新显示出我们修改后的结果(而不需要每次都进行编译)。

(2) 步骤

  • 安装

    1
    npm install --save-dev webpack-dev-server
  • 修改配置文件 webpack.config.js

    1
    2
    3
    4
    5
    module.exports = {
    ···
    devServer: {
    contentBase: './dist',
    },

    可选参数有:

    • contenBase:指示为哪个文件夹提供本地服务,默认为根目录
    • port:端口号
    • inline:页面自动刷新
    • historyApiFallback:在 SPA 页面,依赖 HTML5 的 history 模式
  • 修改 package.json

    通过快捷指令,以便调用本地的 webpack-dev-server

    1
    2
    3
    4
    "scripts": {
    // --open 可以使webpack自动打开浏览器
    "dev": "webpack-dev-server --open"
    },

(3) 停止服务器

ctrl + c

8. webpack-merge

(1) 说明

(2) 步骤

  • 安装

    1
    npm install webpack-merge
  • 重新整理 webpack.config.js 文件:

    • 新建 build 文件夹
    • 新建 base.config.js 文件,放入基础配置文件
    • 新建 dev.config.js 文件,放入开发时的配置文件
    • 新建 prod.config.js 文件,放入生产时的配置文件
  • 修改 base 配置文件如下:

    1
    2
    3
    4
    5
    6
    7
    ···
    module.exports = {
    ···
    output: {
    path: path.resolve(__dirname, '../dist'),
    },
    }
  • 将 dev 和 prod 的配置文件修改如下

    1
    2
    3
    4
    5
    6
    const WebpackMerge = require('webpack-merge');
    const BaseConfig = require('./base.config')

    module.export = WebpackMerge(BaseConfig, {
    ···
    })
  • 在 package.json 中修改 scripts 如下:

    1
    2
    3
    4
    "scripts": {
    "build": "webpack --config ./build/prod.config.js",
    "dev": "webpack-dev-server --open --config ./build/dev.config.js"
    },

八、卸载与安装

1. 卸载

(1) 删除全局 webpack-cli

1
npm uninstall -g webpack-cli

(2) 删除局部 webpack-cli

1
npm uninstall webpack-cli

(3) 删除全局 webpack

1
npm uninstall -g webpack

(4) 删除局部 webpack

1
npm uninstall webpack

2. 安装

(1) 安装 Webpack

1
npm install webpack@版本号 -g --save-dev
  • -g 表示全局安装
  • webpack 可以后跟 @版本号 ,用于安装指定版本,否则会安装最新版本
  • --save-dev 的含义是将安装包信息写入 package.json 文件的 devDependencies 字段中

(2) 安装 Webpack-cli

webpack4.+ 开始 webpack-cli 是必备的

1
npm install --save-dev webpack-cli

(3) 全局安装和局部安装

  • 全局安装意味着本机上所有的项目都将使用它

  • 本地安装可以让每个项目都拥有独立的包,不受全局包的影响,方便项目的移动、复制、打包等。

(4) 检查是否安装成功

在全局或本地执行

1
webpack -v

参考