We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TOC]
模块化是指将一个复杂的系统分解为多个模块以方便编码。
CommonJS是一种被广泛使用的javascript模块化规范,其核心思想是:通过require方法来同步加载依赖的其他模块,通过module.exports导出需要暴露的接口。CommonJS规范的流行得益于Node.js采用了这种方式,后来这种方式被引入到了网页开发中。
CommonJS
javascript
require
module.exports
Node.js
// 导入 const moduleA = require('./moduleA'); // 导出 module.exports = moduleA.someFunc;
CommonJS的优点:
CommonJS的缺点:这样的代码无法直接运行在浏览器环境下,必须通过工具转换成标准的ES5。
AMD也是一种javascript模块化规范,与CommonJS最大的不同在于:它采用了异步的方式去加载依赖的模块。AMD规范主要用于解决针对浏览器环境的模块化问题,最具代表性的实现是requirejs。
AMD
requirejs
// 定义一个模块 define('module', ['dep'], function(dep) { return exports; }); // 导入和使用 require(['module'], function(module) { });
AMD的优点:
AMD的缺点:在javascript运行环境没有原生支持AMD,需要先导入实现了AMD的库后才能正常使用。
ES6模块化是国际标准化组织ECMA提出的javascript模块化规范,它在语言层面上实现了模块化。浏览器厂商和Node.js都宣布要原生支持该规范,它将逐渐取代CommonJS和AMD规范,成为浏览器和服务器通用的模块化解决方案。
// 导入 improt React, {Component} from 'react'; // 导出 export function hello() {}; export default { // ... }
ES6模块化虽然是终极模块化方案,但是它的缺点在于:目前无法直接运行在大部分javascript运行环境下,必须通过工具转换成标准的ES5后才能正常运行。
ES6
从Webpack 2版本开始,Webpack已经内置了对ES6、CommonJS、AMD模块化语句的支持。
Webpack 2
npm i -g webpack webpack-cli
// 安装最新的稳定版本 npm i -D webpack webpack-cli // 安装指定版本 npm i -D webpack@<version> webpack-cli@<version> // 安装最新的体验版本 npm i -D webpack@beta webpack-cli@beta
特别注意:一般不推荐全局安装webpack,原因是可防止不同的项目因依赖不同版本的webpack而导致冲突。
webpack
在编写webpack代码之前,先搭建如下的项目目录:
webpack-demo # 项目名 | |--- dist # 打包后生成的文件目录 | |--- node_modules # 所有的依赖包 | |--- src # 项目源码目录 | | |-- js # js文件目录 | | |-- styles # css文件目录 | |--- webpack.config.js # webpack配置文件 | |--- index.html # html文件 | |--- .gitignore | |--- README.md | |--- package.json
// 安装loader npm i -D style-loader css-loader
module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader?minimize'] } ] }
use
Loader
URL querystring
'css-loader?minimize'
minimize
css-loader
css
向loader传入属性的方式除了可以通过URL querystring实现,还可以通过Object实现,配置如下:
loader
Object
module: { rules: [ { test: /\.css$/, use: ['style-loader', { loader: 'css-loader', // 设置loader相关参数 options: { minimize: true } } ] } ] }
style-loader的工作原理是:将css的内容用javascript里的字符串存储起来,在网页执行javascript时通过DOM操作,动态地向HTML head标签里插入HTML style标签。
style-loader
DOM
HTML head
HTML style
Plugin是用来扩展webpack功能的,通过在构建流程里注入钩子实现,为webpack带来了很大的灵活性。 如果想要使用一个插件,我们只需要require()它,然后把它添加到plugins数组中。我们可以在一个配置文件中因为不同的目的多次使用用一个插件,因此我们可以使用new操作符来创建它的实列。
Plugin
require()
plugins
mini-css-extract-plugin是将css提取到单独文件中的插件,具体配置如下:
mini-css-extract-plugin
npm install --save-dev mini-css-extract-plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { plugins: [ new MiniCssExtractPlugin({ // 指定提取出来的css文件的名称 filename: "[name]_[contenthash:8].css" }) ], module: { rules: [ { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader" ] } ] } }
[name]代表文件的名称,[contenthash:8]代表根据文件内容算出的8位Hash值。
[name]
[contenthash:8]
DevServer会启动一个HTTP服务器用于服务网页请求,同时会帮助启动Webpack,并接收Webpack发出的文件变更信号,通过WebSocket协议自动刷新网页做到实时预览。
DevServer
HTTP
Webpack
WebSocket
npm i -D webpack-dev-server
需要注意的是:DevServer会将Webpack构建出的文件保存在内存中,在要访问输出的文件时,必须通过HTTP服务访问。
Webpack在启动时可以开启监听模式,默认是关闭的,之后Webpack会监听本地文件系统的变化,在发生变化时重新构建出新的结果。Webpack默认关闭监听模式,我们可以在启动Webpack时通过如下命令来开启监听模式:
webpack --watch
通过DevServer启动的Webpack会开启监听模式,当发生变化时重新执行构建,然后通知DevServer。DevServer会让Webpack在构建出的javascript代码里注入一个代理客户端用于控制网页,网页和DevServer之间通过WebSocket协议通信,以方便DevServer主动向客户端发送命令。DevServer在收到来自Webpack的文件变化通知时,通过注入的客户端控制网页刷新。
如果尝试修改index.html文件并保存,则我们会发现这并不会触发以上机制,导致这个问题的原因是:Webpack在启动时会以配置里的entry为入口去递归解析出entry所依赖的文件,只有entry本身和依赖的文件才会被Webpack添加到监听列表里。而index.html文件是脱离了javascript模块化系统的,所以Webpack不知道它的存在。但是要完成上面的实时预览,html页面的bundle.js要直接引入即可,如下html页面代码:
index.html
entry
html
bundle.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"></div> <script src="bundle.js"></script> </body> </html>
为什么http://localhost:8080/bundle.js这样也能访问的到呢?原因是:DevServer会将webpack构建出的文件保存在内存中,DevServer不会理会webpack.config.js里配置的output.path属性的。
http://localhost:8080/bundle.js
webpack.config.js
output.path
除了上面介绍的改动本地入口文件或依赖文件后,会自动打包,然后会自动刷新浏览器即可看到更新效果外,我们还可以使用模块热替换技术,
模块热替换技术能做到在不重新加载整个网页的情况下,通过将已更新的模块替换旧模块,它默认是关闭的,要开启模块热替换,我们只需在启动DevServer时带上--inline参数即可。如下命令:
--inline
webpack-dev-server --inline 或 webpack-dev-server --inline --hot
webpack-dev-server有如下两种启动模式:
webpack-dev-server
在浏览器中运行javascript代码都是编译器输出的代码,但是如果在代码中碰到一个bug的时候,我们不好调式,因此我们需要Source Map来映射到源代码上,Webpack支持生成Source Map,只需在启动时带上--devtool source-map参数即可;如下命令:
bug
Source Map
--devtool source-map
webpack-dev-server --inline --hot --devtool source-map
注意:每次运行如上命令,感觉非常长,因此我们可以在项目的根目录的package.json文件的scripts中添加如下配置:
package.json
scripts
"scripts": { "dev": "webpack-dev-server --devtool source-map --hot --inline" }
加上如上配置后,我们只需要在命令行中运行npm run dev即可;
npm run dev
其他配置常见的选项:
因此在项目中scripts经常会做如下配置:
"scripts": { "dev": "webpack-dev-server --progress --colors --devtool source-map --hot --inline", "build": "webpack --progress --colors" }
这样的话,打包的时候会显示打包进度。
也可以在webpack.config.js中添加如下配置:
// 开启Source Map devtool: 'cheap-module-source-map'
The text was updated successfully, but these errors were encountered:
No branches or pull requests
[TOC]
1. 模块化
1.1 CommonJS
CommonJS
是一种被广泛使用的javascript
模块化规范,其核心思想是:通过require
方法来同步加载依赖的其他模块,通过module.exports
导出需要暴露的接口。CommonJS
规范的流行得益于Node.js
采用了这种方式,后来这种方式被引入到了网页开发中。CommonJS
规范。1.2 AMD
AMD
也是一种javascript
模块化规范,与CommonJS
最大的不同在于:它采用了异步的方式去加载依赖的模块。AMD
规范主要用于解决针对浏览器环境的模块化问题,最具代表性的实现是requirejs
。1.3 ES6模块化
ES6模块化是国际标准化组织ECMA提出的javascript模块化规范,它在语言层面上实现了模块化。浏览器厂商和Node.js都宣布要原生支持该规范,它将逐渐取代CommonJS和AMD规范,成为浏览器和服务器通用的模块化解决方案。
2. 安装webpack
2.1 安装webpack到全局
2.2 安装webpack到项目目录
3. webpack使用
在编写webpack代码之前,先搭建如下的项目目录:
3. 使用Loader
use
属性的值是一个由Loader
名称组成的数组,Loader
的执行顺序是由后到前的;Loader
都可以通过URL querystring
的方式传入参数,例如上述代码中'css-loader?minimize'
中的minimize
就是告诉css-loader
要开启css
压缩。4. 使用Plugin
Plugin
是用来扩展webpack
功能的,通过在构建流程里注入钩子实现,为webpack
带来了很大的灵活性。如果想要使用一个插件,我们只需要
require()
它,然后把它添加到plugins
数组中。我们可以在一个配置文件中因为不同的目的多次使用用一个插件,因此我们可以使用new操作符来创建它的实列。5. 使用DevServer(端口号默认是8080)
DevServer
会启动一个HTTP
服务器用于服务网页请求,同时会帮助启动Webpack
,并接收Webpack
发出的文件变更信号,通过WebSocket
协议自动刷新网页做到实时预览。5.1 实时预览
Webpack
在启动时可以开启监听模式,默认是关闭的,之后Webpack
会监听本地文件系统的变化,在发生变化时重新构建出新的结果。Webpack
默认关闭监听模式,我们可以在启动Webpack
时通过如下命令来开启监听模式:通过
DevServer
启动的Webpack会开启监听模式,当发生变化时重新执行构建,然后通知DevServer
。DevServer
会让Webpack
在构建出的javascript
代码里注入一个代理客户端用于控制网页,网页和DevServer
之间通过WebSocket
协议通信,以方便DevServer
主动向客户端发送命令。DevServer
在收到来自Webpack
的文件变化通知时,通过注入的客户端控制网页刷新。如果尝试修改
index.html
文件并保存,则我们会发现这并不会触发以上机制,导致这个问题的原因是:Webpack
在启动时会以配置里的entry
为入口去递归解析出entry
所依赖的文件,只有entry
本身和依赖的文件才会被Webpack
添加到监听列表里。而index.html
文件是脱离了javascript
模块化系统的,所以Webpack
不知道它的存在。但是要完成上面的实时预览,html
页面的bundle.js
要直接引入即可,如下html
页面代码:为什么
http://localhost:8080/bundle.js
这样也能访问的到呢?原因是:DevServer
会将webpack
构建出的文件保存在内存中,DevServer
不会理会webpack.config.js
里配置的output.path
属性的。5.2 模块热替换
除了上面介绍的改动本地入口文件或依赖文件后,会自动打包,然后会自动刷新浏览器即可看到更新效果外,我们还可以使用模块热替换技术,
模块热替换技术能做到在不重新加载整个网页的情况下,通过将已更新的模块替换旧模块,它默认是关闭的,要开启模块热替换,我们只需在启动
DevServer
时带上--inline
参数即可。如下命令:webpack-dev-server
有如下两种启动模式:5.3 支持Source Map
在浏览器中运行
javascript
代码都是编译器输出的代码,但是如果在代码中碰到一个bug
的时候,我们不好调式,因此我们需要Source Map
来映射到源代码上,Webpack
支持生成Source Map
,只需在启动时带上--devtool source-map
参数即可;如下命令:加上如上配置后,我们只需要在命令行中运行
npm run dev
即可;因此在项目中scripts经常会做如下配置:
这样的话,打包的时候会显示打包进度。
The text was updated successfully, but these errors were encountered: