Hello! 现在我们开始webpack 4的系列教程。我们从webpack的基本概念入手,逐步深入。教程一里我们学习ES6模块打包的基础知识。Webpack 4 提供了一个默认配置,我们就拿这个默认配置来进行讲述。开始吧。
Webpack 4 入门 - 那么,Webpack是啥?
在考虑使用任何工具之前,你要问自己一个很重要的问题,即你使用这个工具来解决什么麻烦。Webpack是一个模块打包器(module bundler)。就是说,它的目的是合并多个模块(以及它们的依赖),输出一个或多个文件。除此之外,webpack还可以做好多事情:比如转译文件,把scss转译成css或把typescript转译成javascript,它还甚至可以压缩你的图像文件!但究竟为什么你想要打包模块呢?
模块打包的目的
回到从前,我们除了使用多个<script>标签,没有其它办法来给浏览器划分javascript代码。我们不得不手动在HTML中写多个源文件。实在不方便。为此社区做了好多努力:CommonJS规范(Node.js实现)和AMD(异步模块定义)规范。有关这些的解读,请查阅Auth0的博客文章。最终,ES6给我们带来了import/export语法。
ES6模块
在ES6中,定义了有关模块的语法。由此,我们有了内建于javascript语言规范的标准模块格式。这并不意味着浏览器目前都已经很好的实现了这些规范,但情况变得越来越好。即使有了ES6模块的原生支持,你仍可能想要把模块打包成少数几个文件。这份教程的主旨是提供使用webpack的全面信息,为此,我们先简洁的概览一下ES6模块的语法。
export
export声明用来创建javascript模块。你能用其来导出对象(包括函数)和原始值。值得注意的是总是在严格模式下编写导出模块。导出有两种类型:命名的和默认的。
命名导出
每个模块可以有多个命名导出。
// lib.js
export function sum(a, b) {
return a + b;
}
export function substract(a, b) {
return a - b;
}
function divide(a, b) {
return a / b;
}
export { divide };
注意,如果你想先声明,后导出,需要用花括弧将其括起来(象上例中的divide函数)
默认导出
每个模块只能有一个默认导出
// dog.js
export default class Dog {
bark() {
console.log('bark!');
}
}
import
import声明用来从其它模块导入。
将模块整体导入
// index.js
import * as lib from './lib.js';
console.log(lib.sum(1,2));
console.log(lib.substract(3,1));
console.log(lib.divide(6,3));
你能给导入的模块取个名字。如果导入整个模块,而这个模块有default export,则其将被设为default属性。
// index.js
import * as Dog from './dog.js';
const dog = new Dog.default();
dog.bark(); // 'bark!'
导入一个或多个命名的导出
// index.js
import { sum, substract, divide } from './lib';
console.log(sum(1,2));
console.log(substract(3,1));
console.log(divide(6,3));
重要一点就是命名必须相应匹配。
导入默认的导出
// index.js
import Dog from './dog.js';
const dog = new Dog();
dog.bark(); // 'bark!'
注意,默认导出能以任何名字导入,因此我们能象下面那样:
// index.js
import Cat from './dog.js';
const dog = new Cat();
dog.bark(); // 'bark!'
ES6模块还支持动态导入,我们将在后面的教程中再去触及。请查阅MDN文档更多的了解exports和inports
(译注:上述有关ES6模块的内容有点简陋,如不熟悉,请先参阅ES6标准入门)
Webpack的基本概念
自版本4开始,webpack提供了一份默认的配置值。如果你想自定义配置,你需要创建一个叫webpack.config.js的配置文件。我们将模仿默认配置值来讲述webpack的基本概念。
webpack.config.js
注意我们写的webpack的配置文件要应用在Node.js中,因此我们按CommonJS类型的模块来写(译注:这里是指webpack.config.js这个文件自己本身写成一个CommonJS模块)。
webpack.config.js导出一个单一的对象。如果你在控制台中启动webpack,将加载这个文件来运行。
入口点(Entry)
Webpack需要一个入口点,用于表明打包从哪里开始。默认如下:
// webpack.config.js
module.exports = {
entry: './src/index.js'
};
其意是指webpack将从'./src/index.js'文件开始打包。如果你在index.js文件中包含了imports声明,webpack就会处理它们。
你可能有多个入口点,但单页应用(SPA),通常只有一个入口点。
出口(Output)
出口配置你打包后的文件输出到哪里。默认值是'./dist/main.js'。
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
}
};
运行webpack
这一节的开始,我们已创建了index.js,它从lib.js中导入了一个函数。让我们启动webpack!记住把这些文件放到src目录下,使得正好匹配默认的配置。
首先要做的是安装Webpack。我们将使用npm来安装。打开你的终端并输入:
npm init -y
npm install webpack
(译注:webpack 4 还需要安装webpack-cli,即 npm install webpack-cli, 这是webpack的命令行工具)
这将创建一个叫node_modules的目录,webpack就在其里面,还创建了两个文件:package.json和package-lock.json。
如果你要对npm中的依赖和和package-lock.json有更多的了解,请参看这篇文章 Keeping you dependencies in order when using npm
现在打开package.json,修改你的脚本:
"scripts": {
"build": "webpack"
}
谢天谢地,运行'npm run build'将从node_modules中启动webpack了。
你会看到在dist目录下创建了一个main.js的文件,它包含了index.js和lib.js的所有内容。
多个入口点
不使用配置文件你也能做到上面所说的。但如果你想做得更多,是时候创建一个配置文件了。
多入口(entries)
配置中的entry属性值不一定要求是字符串。如果你想要配成多个入口点,其值可以为对象。
// webpack.config.js
module.exports = {
entry: {
first: './src/one.js',
second: './src/two.js',
}
};
上面的代码中,我们创建了两个入口点。在开发多页应用的时候可能就需要这么干。
(多个)输出(Outputs)
有一个问题:默认只指定一个输出文件,我们能简单的修补一下:
// webpack.config.js
module.exports = {
entry: {
first: './src/one.js',
second: './src/two.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
看上面的代码,我们指定输出可多于一个文件。所有输出文件都有自己的目标名,这里是first.bundle.js和second.bundle.js,正好与入口点里的名字一一匹配。
小结
今天我们学习了使用webpack打包ES6模块。Webpack 4 提供了默认配置,据此我们解释了一些核心概念,诸如入口点和输出。当然,Webpack功能远不止此。后面接下来的教程中,我们将触及加载器(loaders),甚至自己去写一个。敬请期待!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。