本文作者:IMWeb 黎清龙 原文出处:IMWeb社区 未经同意,禁止转载
webpack 学习小结
1 前言
打包,本质来说就是把许多零散的文件有序的合并成为一个文件,达到前端优化的效果
它的前世今生就不说了,感兴趣的同学可以去学习相关知识
构建 != 打包,反之亦然 打包可以说是构建的一环,构建可以做更多的事情 但是,打包永远都是构建的一个核心
1.1 相关工具
打包工具有很多,下面稍微介绍一下笔者认识的:
1.1.1 grunt
准确来说,grunt 是个构建工具
它只是提供了一些基础能力,出现的较早,社区强大
1.1.2 gulp
gulp 和 grunt 很像,就不多聊了
1.1.3 fis
可以说,fis 比较大,对整个打包过程有一个核心规范和流程,并且总结并提供了打包构建中的3个核心能力
fis 是一个很值得去学习的构建框架
1.1.4 webpack
这个应该是目前最受欢迎与关注的工具了
就个人学习而言,相比其他工具,webpack 是一个专注于打包的工具,因为专注,所以强大
2 打包原理
打包过程实际上很简单,也非常直观,其逻辑如下图所示:
- 确定入口文件:所有程序都会有一个入口,就是 main 程序,打包也不例外
- 获取依赖:分析依赖,打包的关键就是按依赖的顺序来打包,因此这是打包最关键的环节
- 确认出口文件:大多数情况下,打包最终都是输出一个文件,但是也可能会打包成多个,比如common,异步文件等
- 打包:最终输出内容
3 webpack
webpack 的基本使用就不介绍了,看一下文档就知道了
实际上 webpack 的核心是依赖分析,把依赖分析出来了,其他都是细枝末节了
比如 支持什么模块化规范,比如插件等等
使用 webpack 主要是看怎么 config 下面看看 webpack 官方文档的目录:
看到 config 目录那么多,就说明 webpack 的功能有多大
那么多内容可能无从下手,但是大多数情况下只需要关注核心的一些配置即可
下面主要讲解上图的红框部分
3.1 entry
这个就是【入口文件】配置,通过这个 option 来确定入口文件,它有3种格式:
- string:指定入口文件
- array:多个入口文件,最终打包到一起
- object:多 chunk,key 为 chunk 的 名字,value 指定这 chunk 的入口文件
string 和 array 最终会打包成一个文件,object 则可以打包出多个文件
3.2 output
配置【出口文件】
它主要做两种事情:
- 出口文件名称与路径
- 出口文件的格式
看下面的例子:
代码语言:javascript复制// js/a.js
require('./c.js');
var a = 1;
// js/b.js
require('./c.js');
var b = 1;
// js/c.js
var c = 1;
// webpack.config.js
module.exports = {
entry: {
a: './js/a.js',
b: './js/b.js'
},
output: {
path: __dirname '/dist',
filename: "[name].js"
}
};
- filename 指定输出文件的文件名,不建议带路径
- path 这个指定输出文件的文件路径
上面就是输出多文件的配置
如果是要打包库文件,则需要用常规的模块包裹头,webpack 也能轻松支持:
代码语言:javascript复制module.exports = {
entry: {
a: './js/a.js'
},
output: {
path: __dirname '/dist',
filename: "L.js",
library: 'L',
libraryTarget: 'umd'
}
};
输出的L文件就有了常规模块化包裹头:
代码语言:javascript复制(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["L"] = factory();
else
root["L"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
// ...
3.3 resolve
resolve 主要是分析依赖时的路径识别的配置
上面的例子中:a.js 和 b.js 文件都是在js文件夹里面的,然后 require 的时候要用相对路径
通过 resolve 可以帮助我们可以书写更加简单方便的依赖路径,比如:
代码语言:javascript复制// main.js
require('a');
var main = 1;
// webpack.config.js
var path = require('path');
module.exports = {
entry: {
b: './js/b.js',
c: './main.js'
},
output: {
path: __dirname '/dist',
filename: "[name].js",
},
resolve: {
root: [
path.resolve('./js/')
]
}
};
如果没有 resolve.root 的配置,则需要写成:require('./js/a')
3.4 externals
externals 是配置外部依赖的,如果使用某些第三方库的时候,就可以通过这个配置来识别外部第三方库的依赖 比如:
代码语言:javascript复制module.exports = {
entry: './main.js',
output: {
filename: 'L.js',
library: 'L',
libraryTarget: 'umd'
},
externals: {
'jquery': {
root: 'jquery',
amd: 'jquery',
commonjs2: 'jquery',
commonjs: 'jquery'
}
}
};
这个配置显示将要打包的库文件要依赖 jquery 库,打包之后的文件如下:
代码语言:javascript复制(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("jquery"));
else if(typeof define === 'function' && define.amd)
define(["jquery"], factory);
else if(typeof exports === 'object')
exports["Q"] = factory(require("jquery"));
else
root["Q"] = factory(root["jQuery"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_4__) {
return /******/ (function(modules) { // webpackBootstrap
3.5 watch
对于一个工具来说,watch 功能是非常重要的
3.6 plugins
对于一个成熟的框架,插件化是扩展性的一个重要的功能点,感兴趣的同学可以深入学习
4 小结
webpack 是一个专注于打包的工具,它使用简单,功能强大
而且可以作为一个构建框架的打包核心插件,比如grunt,gulp
本文仅仅介绍了webpack的一些核心属性,不多,但是已经可以满足绝对部分需求