思考这样一个问题,你对webapack究竟了解多少?大部分时间我们忙于业务开发,很少去思考这个问题,项目已经配置好了,我们只管开发就好了,陷入业务开发中,就没有时间去思考别的问题,这是一个普遍现象。
按照我们平常的理解,webpack就是一个前端打包工具,术语叫javascript应用程序的静态资源模块打包器
。
有了这个概念以后,我们就可以接着去思考下一个问题,既然它是一个静态资源打包器。那么它具体负责处理哪些资源呢?
很简单:JS代码,css样式,图片,字体,数据。而这些资源通常情况下会借助Loader进行处理,比如:处理css的css-loader,style-loader,处理图片的file-loader,处理数据的CSV-loader等。
处理了资源后,如何进行打包呢?打包的原理和过程这里就不提了,没看过源码,看了估计也看不懂。这里只分享一下日常开发中常用的一些配置技巧。
项目中常用的配置技巧有以下几点:一,代码分割。二,懒加载。三,匀场技术。四,source Map。
代码分割的使用场景是:假如我们不使用代码分割code spliting,很可能出现的一种情况是我们所有的代码最终都打包到一个bundle中,如果这个文件过大,那么必然会影响我们的程序的加载时间,进而影响体验。
日常配置代码分割的方法有三种:1. 配置多个入口。2.使用CommonsChunkPlugin
插件。3.动态导入。配置多个入口需要我们手动去添加入口文件,如:
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
another: './src/another-module.js'
},
plugins: [
new HTMLWebpackPlugin({
title: 'Code Splitting'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
使用CommonsChunkPlugin
插件需要我们在配置文件中填写该插件,如:
const path = require('path');
+ const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
another: './src/another-module.js'
},
plugins: [
new HTMLWebpackPlugin({
title: 'Code Splitting'
- })
+ }),
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'common' // 指定公共 bundle 的名称。
+ })
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
动态导入是日常开发中常用的技巧,如:
async function getComponent() {
var element = document.createElement('div');
// 动态导入
const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}
getComponent().then(component => {
document.body.appendChild(component);
});
懒加载的使用场景是真正发生交互时,再去加载某些某块儿。比如当用户点击事件发生时,执行某些操作。
import _ from 'lodash';
function component() {
var element = document.createElement('div');
var button = document.createElement('button');
var br = document.createElement('br');
button.innerHTML = 'Click me and look at the console!';
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
element.appendChild(br);
element.appendChild(button);
// Note that because a network request is involved, some indication
// of loading would need to be shown in a production-level site/app.
button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {
var print = module.default;
print();
});
return element;
}
document.body.appendChild(component());
shimming匀场技术的使用场景是,当一个模块或者遍历,或者是我们引入的别的包需要做多个地方引用时,我们可以借助这技术点,将其转变为全局变量,当然,这个技术点的实现需要借助ProvidePlugin
插件。比如我们在多个地方使用了lodash:
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.ProvidePlugin({
_: 'lodash'
})
]
};
这样我们就可以将lodash作为全局变量,在代码任意地方使用。
source Map的使用场景是用于追踪代码中的错误和警告。通常通过devtool属性进行配置,这个属性用于控制是否生成,以及如何生成source Map。它的配置有一个参照表:
devtool | 构建速度 | 重新构建速度 | 生成环境 | 品质 |
---|---|---|---|---|
none | +++ | +++ | yes | 打包后的代码 |
eval | +++ | +++ | no | 生成后的代码 |
cheap-eval-source-map | + | ++ | no | 转换过的代码(仅限行) |
cheap-module-eval-source-map | o | ++ | no | 原始源代码(仅限行) |
eval-source-map | -- | + | no | 原始源代码 |
cheap-source-map | + | 0 | no | 转换过的代码(仅限行) |
cheap-module-source-map | 0 | - | no | 原始源代码(仅限行) |
source-map | -- | -- | yes | 原始源代码 |
hidden-source-map | -- | -- | yes | 原始源代码 |
nosources-source-map | -- | -- | yes | 原始源代码 |
+++ 非常快速, ++ 快速, + 比较快, o 中等, - 比较慢, -- 慢
一个常见的问题是生成环境如何调试代码,就是配置devtool即可。
本文分享自 JavaScript高级程序设计 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!