精益 React 学习指南 (Lean React)- 2.2 webpack

书籍完整目录

2.2 webpack

超级产品经理,
document.getElementById('AppRoot')
);

第四步:运行 webpack

$ webpack
执行结果:

Hash: ae2a037c191c18195b6a
Version: webpack 1.13.1
Time: 1016ms
Asset Size Chunks Chunk Names
a.js 1.42 kB 0 [emitted] a
index.js 700 kB 1 [emitted] index

  • 169 hidden modules
    浏览器中打开 index.html 会显示 Hello World

2.2.6 webpack loaders

在配置 JSX 的过程中,使用到了 loader, 前面已经介绍过 webpack 的核心功能包含 loader,通过 loader 可以将任意资源转化为 javascript 模块。

loader 定义

Loaders are transformations that are applied on a resource file of your app.
(Loaders 是应用中源码文件的编译转换器)

也就是说在 webpack 中,通过 loader 可以实现 JSX 、Es6、CoffeeScript 等的转换,

loader 功能

  1. loader 管道:在同一种类型的源文件上,可以同时执行多个 loader , loader 的执行方式可以类似管道的方式,管道执行的方向为从右到左。

  2. loader 可以支持同步和异步

  3. loader 可以接收配置参数

  4. loader 可以通过正则表达式或者文件后缀指定特定类型的源文件

  5. 插件可以提供给 loader 更多功能

  6. loader 除了做文件转换以外,还可以创建额外的文件

loader 配置

新增 loader 可以在 webpack.config.js 的 module.loaders 数组中新增一个 loader 配置。

一个 loader 的配置为:

{
// 通过扩展名称和正则表达式来匹配资源文件
test: String ,
// 匹配到的资源会应用 loader, loader 可以为 string 也可以为数组
loader: String | Array
}
感叹号和数组可以定义 loader 管道:

{
module: {
loaders: [
{ test: /.jade$/, loader: "jade" },
// => .jade 文件应用 "jade" loader

        { test: /\.css$/, loader: "style!css" },        { test: /\.css$/, loaders: ["style", "css"] },        // => .css 文件应用  "style" 和 "css" loader      ]}

}
loader 可以配置参数

{
module: {
loaders: [
// => url-loader 配置 mimetype=image/png 参数
{
test: /.png$/,
loader: "url-loader?mimetype=image/png"
}, {
test: /.png$/,
loader: "url-loader",
query: { mimetype: "image/png" }
}

    ]}

}

使用 loader

第一步: 安装

loader 和 webpack 一样都是 Node.js 实现,发布到 npm 当中,需要使用 loader 的时候,只需要

$ npm install xx-loader --save-dev

// eg css loader
$ npm install css-loader style-loader --save-dev

第二步:修改配置

{
entry: {
index: './src/index.js',
a: './src/a.js'
},
output: {
path: './dist/',
filename: '[name].js'
},
module: {
loaders: [{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
}, {
test: /.css$/,
loader: "style-loader!css-loader"
}]
}
}

第三步:使用

前面我们已经使用过 jsx loader 了, loader 的使用方式有多种

  1. 在配置文件中配置

  2. 显示的通过 require 调用

  3. 命令行调用

显示的调用 require 会增加模块的耦合度,应尽量避免这种方式

以 css-loader 为例子,在项目 src 下面创建一个 css

src/style.css

body {
background: red;
color: white;
}
修改 webpack 配置 entry 添加

entry: {
index: ['./src/index.js', './src/style.css']
}
执行 webpack 命令然后打开 index.html 会看到页面背景被改为红色。

最终的编译结果为:

....
function(module, exports, webpack_require) {
exports = module.exports =
webpack_require
(171)();
exports.push([module.id, "\nbody {\n background: red;\n color: white;\n}\n", ""]);
}
....
可以看到 css 被转化为了 javascript, 在页面中并非调用 的方式, 而是使用 inline 的 .....

另外一种方法是直接 require, 修改 src/index.js:

var css = require("css!./style.css");
编译结果相同。

2.2.7 webpack 开发环境与生产环境

前端开发环境通常分为两种,开发环境和生成环境,在开发环境中,可能我们需要日志输出,sourcemap ,错误报告等功能,在生成环境中,需要做代码压缩,hash 值生成。两种环境在其他的一些配置上也可能不同。

所以为了区分,我们可以创建两个文件:

  1. webpack.config.js // 开发环境

  2. webpack.config.prod.js // 生产环境

生产环境 build 用如下命令:

webpack --config webpack.config.prod.js
在本章深入 webpack 小节中会更多的介绍生产环境中的优化

2.2.8 webpack 插件

webpack 提供插件机制,可以对每次 build 的结果进行处理。配置 plugin 的方法为在 webpack.config.js 中添加:

{
plugins: [
new BellOnBundlerErrorPlugin()
]
}
plugin 也是一个 npm 模块,安装一个 plugin :

$ npm install bell-on-bundler-error-plugin --save-dev

2.2.9 webpack 分割 vendor 代码和应用业务代码

在上面的 jsx 配置中,我们将 React 和 ReactDOM 一起打包进了项目代码。为了实现业务代码和第三方代码的分离,我们可以利用
CommonsChunkPlugin 插件.

修改 webpack.config.js

{
entry: {
index: './src/index.js',
a: './src/a.js',
// 第三方包
vendor: [
'react',
'react-dom'
]
},
output: {
path: './dist/',
filename: '[name].js'
},
module: {
loaders: [{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
}, {
test: /.css$/,
loader: "style-loader!css-loader"
}]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(/ chunkName= /"vendor", / filename= /"vendor.bundle.js")
]
}
执行 webpack 命令,输出日志:

Hash: f1256dc00b9d4bde8f7f
Version: webpack 1.13.1
Time: 1459ms
Asset Size Chunks Chunk Names
a.js 109 bytes 0 [emitted] a
index.js 10.9 kB 1 [emitted] index
vendor.bundle.js 702 kB 2 [emitted] vendor
[0] multi vendor 40 bytes {2} [built]
[0] multi index 40 bytes {1} [built]

  • 173 hidden modules
    index.js 体积变小了,多出了 vendor.bundle.js

2.2.10 webpack develop server

在前端开发的过程中,通常需要启动一个服务器,把开发打包好的前端代码放在服务器上,通过访问服务器访问并测试(因为可以有些情况需要 ajax 请求)。 webpack 提供了一个机遇 node.js Express 的服务器 - webpack-dev-server 来帮助我们简化服务器的搭建,并提供服务器资源访问的一些简单配置。

安装 webpack-dev-server

$ npm install webpack-dev-server -g

启动 webpack-dev-server

$ webpack-dev-server --content-base ./
--content-base ./ 参数表示将当前目录作为 server 根目录。 命令启动过后,会在 8080 端口启动一个 http 服务,通过访问 http://localhost:8080/index.html 可以访问 index.html 内容。

如果访问提示报错:

Uncaught ReferenceError: webpackJsonp is not defined
原因是 html 中没有引用 vendor.bundle.js, 修改 html :

修改 index.html 过后可以看到正确结果

代码监控

webpack-dev-server 除了提供 server 服务以外, 还会监控源文件的修改,如果源文件改变了,会调用 webpack 重新打包

修改 style.css 中的内容为:

body {
background: whitesmoke;
color: # 333;
font-size: 100px;
}
可以看到输出以下日志:

[168] ./~/react/lib/renderSubtreeIntoContainer.js 466 bytes {2} [built]
webpack: bundle is now VALID.
webpack: bundle is now INVALID.
Hash: cc7d7720b1a0fcbef972
Version: webpack 1.13.0
Time: 76ms
chunk {0} a.js (a) 32 bytes {2}

  • 1 hidden modules
    chunk {1} index.js (index) 10.3 kB {2}
    [170] ./~/css-loader!./src/style.css 230 bytes {1} [built]
  • 5 hidden modules
    chunk {2} vendor.bundle.js (vendor) 665 kB
  • 168 hidden modules
    webpack: bundle is now VALID.
    这个时候说明代码已经修改了,但是这个时候刷新浏览器过后,背景是没有改变的,原因是 webpack-dev-server 的打包结果是放在内存的,查看 dist/index.js 的内容实际上是没有改变的,那如何访问内存中的打包内容呢?

修改 webpack.config.js 的 output.publicPath:

output: {
path: './dist/',
filename: '[name].js',
publicPath: '/dist'
// webpack-dev-server 启动目录是 /, /dist 目录是打包的目标目录相对于启动目录的路径
},
重新启动

$ ctrl + c 结束进程$ webpack-dev-server

修改 style.css 再刷新页面,修改的内容会反映出来。

自动刷新

上面的配置已经能做到自动监控代码,每次修改完代码,刷新浏览器就可以看到最新结果,但是 webpack-dev-server 还提供了自动刷新功能,有两种模式。

Iframe 模式

修改访问的路径: http://localhost:8080/index.html -> http://localhost:8080/webpack-dev-server/index.html 。这个时候每次修改代码,打包完成过后都会自动刷新页面。

  1. 不需要额外配置,只用修改路径

  2. 应用被嵌入了一个 iframe 内部,页面顶部可以展示打包进度信息

  3. 因为 iframe 的关系,如果应用有多个页面,无法看到当前应用的 url 信息

inline 模式

启动 webpack-dev-server 的时候添加 --inline 参数

  1. 需要添加 --inline 配置参数

  2. 没有顶部信息提示条,提示信息在控制台中展现

热加载 (hot module replacement)

webpack-dev-server 还提供了模块热加载的方式,在不刷新浏览器的条件下,应用最新的代码更新,启动 webpack-dev-server 的时候添加 --inline --hot 参数就可以体验。

$ webpack-dev-server --inline --hot
修改代码在浏览器控制台中会看到这样的日志输出:

[HMR] Waiting for update signal from WDS...
vendor.bundle.js:670 [WDS] Hot Module Replacement enabled.
2vendor.bundle.js:673 [WDS] App updated. Recompiling...
vendor.bundle.js:738 [WDS] App hot update...
vendor.bundle.js:8152 [HMR] Checking for updates on the server...
vendor.bundle.js:8186 [HMR] Updated modules:
vendor.bundle.js:8188 [HMR] - 245
vendor.bundle.js:8138 [HMR] App is up to date.

在 webpack.config.js 中配置 webpack develop server

修改 webpack.config.js 添加:

plugins: [
new webpack.optimize.CommonsChunkPlugin(
/ chunkName= /"vendor",
/ filename= /"vendor.bundle.js", Infinity),
// 需要手动添加 HotModuleReplacementPlugin , 命令行的方式会自动添加
new webpack.HotModuleReplacementPlugin()
],
devServer: {
hot: true,
inline: true
}
不加参数直接执行 webpack-dev-server

$ webpack-dev-server
webpack-dev-server 还提供了其他的一些功能, 如:

  1. 配置 proxy

  2. 访问 node.js API

  3. 和现有的 node 服务集成

基于这些功能可以实现很多自定义的功能。

关键字:leanreact, react.js, 前端开发, 前端工程化


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部