0%

webpack入门

webpack 主要工作流程

webpack的主要工作是将模块打包,这些模块可能包括js代码模块css模块,一些其他静态资源等。无论是在pro模式下还是在dev模式下本质上都是将模块打包成资源,并依赖一些插件依照一些规范对这些资源进行一定的工程化整合,解决一些前端开发、部署的公共性问题。使其成为一个开发或者构建的封闭实体。

开发流程

就开发过程而言一般需要一个开发服务器(WebpackDevServer)、一个代码解析器(babel)(ES6或Ts代码需要转化为es5 js代码),一个资源整合器(webpack)。

整体流程上相对比较简单,根据webpack的config生成webpack,根据WebpackDevServer的config生成WebpackDevServer,监听端口和host,启动服务,主体流程就算走完。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 设置环境为开发环境
process.env.NODE_ENV = 'development';
process.env.BABEL_ENV = 'development';


// webpack
const webpack = require('webpack');
// webpackConfig
const webpackConfig = require('../config/webpack.config');

// webpackDevServerConfig
const webpackDevServerConfig = require('../config/webpackDevServer.config');
// webpack 开发服务器
const WebpackDevServer = require('webpack-dev-server');


// 创建devServer
const devServer = new WebpackDevServer(webpack(webpackConfig), webpackDevServerConfig);

// 监听端口
devServer.listen(3000, 'localhost');

代码解析器(babel)

这里babel提供了将es6代码解析成es5代码、将jsx代码解析成通用代码的服务。

配置babelconfig

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = function (api) {
api.cache(true)
const presets = [
// babel 预设套件 根据配置的目标浏览器或者运行环境来自动将ES2015+的代码转换为es5
"@babel/preset-env",
// 将 jsx 代码解析成通用代码
"babel-preset-react-app"
];
return {
presets,
};
}

资源整合器(webpack)

这里webpack主要提供了设置一些基础参数、根据这些参数调用babel去解析当前代码,并将解析完毕的js代码插入已设定的模板html文件

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
31
32
33
34
35
36
37
38
39
40
41
42
// webpack 配置信息
const paths = require('./paths');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

// 设置开发环境和生产环境
mode: process.env.NODE_ENV === 'production' ? 'production' :
process.env.NODE_ENV === 'development' && 'development',

// 入口
entry: paths.mainjs,
// 出口
output: {
path: paths.build,
filename: 'bundle.[hash:8].js'
},
// loader
// 针对不同的文件,选择不同的loader
// loader本质上是一些function,对传入的资源进行处理并返回已处理的资源
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: paths.src,
loader: require.resolve('babel-loader'),
options: {
// 指定 babelConfig 文件(未指定的话会在运行目录下搜索)
configFile: paths.babelConfig
}
}
]
},

plugins: [
// HtmlWebpackPlugin 插件 提供了将已构建的代码插入模板html文件的功能
new HtmlWebpackPlugin({
// 选择模板
template: paths.indexHTML
})]
};

开发服务器(WebpackDevServer)

这里的开发服务器主要提供了web代理服务,资源文件压缩、开发热替换、服务启动后自动打开网页等服务。

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
// app的根目录
contentBase: paths.public,
// 开启gzip压缩
compress: true,
// 端口号
port: 3000,
// 启动webpackDevServer后直接打开网页
open: true,
// 开发热替换(不用重新start)
hot: true,
};

构建流程

构建过程相对于开发过程,一般上来讲少了开发服务器。只需要管理构建目录、构建资源文件、以及文件写入。

构建目录需要自己管理、旧有文件的清楚、目录结构的配置。构建资源文件、文件写入由webpack完成。所以这一块就更加简单。

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 设置环境为开发环境
process.env.NODE_ENV = 'production';
process.env.BABEL_ENV = 'production';

// 引入 webpack
const webpack = require('webpack');
const config = require('../config/webpack.config');
const paths = require('../config/paths');
const fs = require('fs');

// 删除旧文件
removeOldfiles();

// 启动 webpack
const compiler = webpack(config);

// 错误回显
compiler.run((err, stats) => {
let messages;
if (err) {
messages = {
errors: [err.message]
};
console.log(messages);
} else {
messages = stats.toJson({ all: false, warnings: true, errors: true });
}
if (messages.errors.length) {
if (messages.errors.length > 1) {
messages.errors.length = 1;
}
console.log(new Error(messages.errors.join('\n\n')));
}
});

function removeOldfiles() {
const directoryList = [paths.build];

while (directoryList.length) {
let path = directoryList[0];
let filse = fs.readdirSync(path);
directoryList.shift();
filse.forEach((item) => {
if (fs.lstatSync(path + '/' + item).isDirectory() === true) {
directoryList.push(path + item + '/');
} else {
fs.unlink(path + '/' + item)
}
})
}
}

以上 webpack 的主要工作流程就算介绍完毕。