webpack基础(一):为什么选择Webpack

这是半个月前在 FrontendMasters 看的 Webpack 视频,过了半个月,做一下总结以及回顾。这篇时第一部分,Webpack 基础。

script 标签加载问题

难题

回到没有前端工具的最原始的时代,如果我们有一段 Javascript 代码,我们有两种方式加载它:

  1. 直接在 html 书写这段 script。

  2. 使用<script src="*.js"></script>

随之带来的问题有:

  1. 无法被压缩。

  2. 过多的script标签。

    HTTP1.1 情况下,浏览器的同时最大连接数为:

version Maximun connections
Internet Explorer® 7.0 2
Internet Explorer 8.0 and 9.0 6
Internet Explorer 10.0 8
Internet Explorer 11.0 13
Firefox® 6
Chrome™ 6
Safari® 6
Opera® 6
iOS® 6
Android™ 6
  1. 脚本难以维护。
    • 作用域
    • 脚本尺寸
    • 可读性
    • 及其脆弱
    • 整体文件过大

解决方法?

这时 IIFE(Immediately Invoked Function Expression)立即执行函数出现在人们眼前。

一个最简单的 IIFE 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var outerScope = 1;

const whatever = function(dataNowUsedInside) {
outerScope = 4;
return {
someAttribute: 'youwant'
};
};

console.log(outerScope);
// > 1
// 内部赋值没有影响外部作用域
// whatever.someAttribute
// > 'youwant'

那么现在我们需要做的就是,把每一个文件都当作一个 IIFE(揭示模块)调用。

现在我们可以利用 Make, Grunt, Gulp, Broccoli, Brunch, StealJS 等 “安全” 的组合文件,而不用担心作用域冲突。但是,这样就完美了吗?

这样大量的使用 IIFE,也带来了很多 问题

  1. 每一次文件改变都需要所有 IIFE 全部执行一遍。

  2. DEAD CODE: 连接文件并没有助于我们跨文件使用代码。利用使用 lodash.js 等库,需全部加载。

  3. 大量使用 IIFE,调用会非常慢。

  4. 只能同步加载,没有异步加载,无法实现 lazy code

模块的历史

伴随着 Node.js 诞生的 CommonJs ( Module 1.0 )。采用静态语法分析,使用 NPM + Node + Modules 的生态。

Node.jsCommonJs 存在的问题:

  1. 不支持浏览器

  2. 没有活动绑定,存在循环引用的问题。

  3. 模块同步解析加载,会很慢。

不支持浏览器的解决方法

  • 使用类似 Browserify (static) 工具。
  • 使用 RequireJS (loader)。
  • 使用 SystemJS (loader)。

模块同步解析加载的难题

CommonJS 模块方式不支持静态异步/延迟加载,所有模块都绑定在文件顶部。

在浏览器中,我们则需要动态的 CommonJS

浏览器中,可以使用 AMD 模块, 或者还有 AMD + CommonJS 方式。不过这些方式对于需要延迟加载的模块来讲还是太同步了。而且,这么多种上传方式,没有一种标准的语法,没有一个真正的模块系统。

ESM(EcmaScriptModule)模块

ESM 的出现解决了 CommonJS 的不支持静态异步和延迟加载功能。

1
2
3
4
import { uniq, forOf, bar } from 'lodash-es';
import * as utils from 'utils';

export const uniqConst = uniq([1, 2, 3, 4]);

现在我们直接看下 ESM 的优点:

  1. 可重复使用。

  2. 良好的封装性。

  3. 易于组织。

  4. 便于使用。

当然 ESM 也有缺点:

  1. ESM 在 Node 的模块中,使用的很少。

  2. ESM 可以直接在浏览器中使用,但非常非常非常慢。(因为经常容易出一些错,使代码崩溃)。

除此之外,还有一些问题,每一个库的作者都有自己喜欢的模块加载方式,代码也是不同的。目前为止我们讨论的都是 JavaScript 。到目前为止,每种文件类型都必须有处理它的特定方法。所以接下来就要介绍 Webpack 了。

介绍 Webpack

Webpack 是模块打包器,可以让你编写任意的模块格式,甚至混合的格式,通过 Webpack 打包,使浏览器能够读取他们。

Webpack 支持 静态异步打包 ,而且它具有丰富的生态系统,可以说是今天发布 JavaScript 的最佳方式了。

Webpack 诞生于 modules-webmake, 为了给 modules-webmake 添加 Code splitting ,诞生了 Webpack。

配置 Webpack

所以如何配置 Webpack 呢?

  1. 使用 config ,如 webpack.config.js ,配置文件本身就是一个模块。
1
2
3
4
5
6
7
8
9
10
module.exports = {
entry: {
vendor: './src/vendors.ts',
main: './src/main.browser.ts'
},
output: {
path: 'dist/',
filename: '[name].bundle.js'
}
};
  1. 使用 Webpack-Cli 。
1
2
3
$ webpack <entry.js> <result.js> --colors --progress

$ webpack-dev-server --port=9000
  1. Node Api。
1
2
3
4
5
6
7
8
9
10
11
12
13
var webpack = require('webpack');

// returns a Compiler instance
webpack(
{
// configuration object here!
},
function(err, stats) {
// …
// compilerCallback
console.error(err);
}
);

引用

评论

加载中,最新评论有1分钟延迟...