Webpack 4教程 - 第六部分 增强开发时体验
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。
原文出处:https://wanago.io/2018/08/06/webpack-4-course-part-six-increasing-development-experience
今天我们将介绍mode属性的development值。它会自动为你配置Webpack以简化开发过程。除此之外,我们还会介绍webpack-dev-server——包括模块热替换。开始吧!
开发体验优化的其中一步是让Webpack运行在watch模式下。试试webpack --watch。现在每当你对源码做出修改,Webpack会重新编译你的工程然后输出。webpack-dev-server则做得更多。它不是把输出文件写到文件夹下,而是直接把它们写入内存。在构建完之后,输出可作为本地服务器资源被访问。
运行 webpack-dev-server
首先是安装它。
npm install webpack-dev-server
然后是在你的package.json文件中加入它:
"scripts": {
"build": "webpack",
"start": "webpack-dev-server"
}
···
现在就可以使用`npm start`来启动它。你会看到下面的提示信息:
```bash
「wds」: Project is running at http://localhost:8080/
剩下的事情只是在浏览器中打开http://localhost:8080/了。
模块热替换
为进一步优化你的开发体验,可以使用模块热替换,你甚至跳过刷页面的需求。比如,当你对某些样式做了修改,不必刷新整个页面就可以看到效果。
在第四节教程我们曾使用了MiniCssExtractPlugin。请注意,在写文本时,对MiniCssExtractPlugin的热模块更新支持还没有实现。更多信息请可查看Github上的此issue。在当前开发环境,你可能需要使用的是style-loader。
当你运行webpack-dev-server时,它使用与正常构建时相同的配置文件。你可以在webpack.config.js中加入一个叫devServer的参数来进行额外的配置。我们需要它来开启模块热替换。
// webpack.config.js
const webpack = require('webpack'); module.exports = {
devServer: {
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
注意,当开启 -hot 标志以运行 webpack-dev-server 时也会在plugins里加入HotModuleReplacementPlugin。如果你添加了两次,可能会出现问题。
这对于我们的CSS调试是很有吸引力的。但当修改是JavaScript时,还需点额外步骤。
// index.js
import { divide } from "./divide"; console.log(`6 / 2 = ${divide(6,2)}`); if(module.hot) {
module.hot.accept();
}
// divide.js
export function divide(a, b) {
return a / b;
}
运行module.hot.accept()会让模块可热替换。这同样适用于它引入的所有其他模块。上面的代码意味着,index.js中的accept()让divide模块能够被热替换。
运行module.hot.accept()函数时可以传参,如果你感兴趣,请查看文档。
当使用HotModuleReplacementPlugin插件时,如果输出文件名中使用了chunkhash字段,就可能会出现一些问题。这种情况下,只在开发环境下使用HotModuleReplacementPlugin是个好主意(而且避免使用chunckhash)。
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const isDevServer = require.main.filename.includes('webpack-dev-server');
const plugins = [
new HtmlWebpackPlugin({ template: './src/index.html' }),
];
if(isDevServer) {
plugins.push(new webpack.HotModuleReplacementPlugin());
} module.exports = {
output: {
filename: isDevServer ? '[name].bundle.js' : '[name].[chunkhash].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
plugins,
devServer: {
hot: true
}
}
webpack-serve
译者注:由于webpack-serve其实已经不再维护了。推荐仍然使用上面所说的webpack-dev-sever。
mode: "development"
在之前的课程,我们介绍了mode属性的production值。现在该轮到development了。让我们看看它为我们做了我们。
DefinePlugin
如之前所说,这个插件允许你创建编译时的全局常量。
因为这个插件也在mode: produnction中使用,更多信息可查看教程的第五部分。
这次它的值为process.env.NODE_ENV: JSON。stringify("development"):
module.exports = {
mode: "development",
// 使用 mode: "development" 会添加以下配置:
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("development")
}),
]
}
NamedModulesPlugin
这是在使用mode: "development"时默认加入的另一个插件。它在使用模块热替换时很有用。有了NamedModulesPlugin,我们能够看到被替换模块的相对路径。
[WDS] App updated. Recompiling...
[WDS] App hot update...
[HMR] Checking for updates on the server...
[HMR] Updated modules:
[HMR] - ./src/style.css
[HMR] App is up to date
否则我们只会看到一个id,而不是像./src/style.css这样的路径。
NamedChunksPlugin
它的左右和NamedModulesPlugin类似。有了它,不仅模块能看到名字,chunk也能。当应用在浏览器中运行起来是,你可以在window.webpackJsonp属性中查看它们。
使用NamedModulesPlugin和NamedChunksPlugin的一个额外好处是,当添加和删除依赖时,打包不再需要使用模块的顺序id。因为这些id和名字会在最终的输出产物中使用,修改它们会导致文件哈希值的变化,即使这些文件使用的模块本身并没有改变。使用以上两个插件会帮助你处理浏览器的缓存问题。让我们来比较一下代码:
没使用NamedModulesPlugin和NamedChunksPlugin:
// 输出产物
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[2],{
/***/ 6:
(...) // divide.js module output code /***/ 7:
(...) // substract.js module output code
]);
使用了NamedModulesPlugin和NamedChunksPlugin:
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["utilities~main"],{
/***/ "./src/utilities/divide.js":
(...) // divide.js module output code
/***/ "./src/utilities/substract.js":
(...) // substract.js module output code
]);
Devtool
除了添加插件,设置mode: "development"还做了一件事,即通过设置devtool的值为eval开启了源码映射(Source Map)。
// webpack.config.js
module.exports = {
mode: "development",
// 使用 mode: "development:" 添加了以下配置
devtool: "eval"
}
转译、压缩和打包你的代码能让你的用户有更好的体验。经过这些步骤之后,代码变得更精简和高效。而调试这样的代码则变得非常困难。因此,引入了源码映射(Source Map)。它们把输出后的的代码与源码对应起来。有了它,相对于浏览器真正运行的打包后的输出,你能看到其对应的源码,从而更加容易地使用调试工具和设置断点。我们会在接下来的课程中对源码映射做进一步介绍,但如果你需要现在就定制它,可查看它的文档。
总结
Webpack是开发现代Web应用的强大工具。它不仅让你优化生产环境的代码,而且还可以并定制,用以增强开发时的体验。这次我们介绍了如何运行开发时服务器,以及把mode属性设成development的一些作用。我们还学习使用了模块的热替换。所有这些组合起来,能帮你更容易和更快地开发应用。
Webpack 4教程 - 第六部分 增强开发时体验的更多相关文章
- 【工业串口和网络软件通讯平台(SuperIO)教程】六.二次开发导出数据驱动
SuperIO相关资料下载:http://pan.baidu.com/s/1pJ7lZWf 1.1 导出数据接口的作用 在数据集成系统项目中,要么是自已集成其他厂家的设备,要么是其他厂家集成自己 ...
- Android简易实战教程--第六话《开发一键锁屏应用2·完成》
转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/51885687点击打开链接 上一篇,初步开发了这个应用,功能都有了(见http:// ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(六):了解MessageHandler
上一篇<Senparc.Weixin.MP SDK 微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK>我们讲述了如何使用Senparc.Weixin.MP SDK ...
- iOS 11开发教程(六)iOS11Main.storyboard文件编辑界面
iOS 11开发教程(六)iOS11Main.storyboard文件编辑界面 在1.2.2小节中提到过编辑界面(Interface builder),编辑界面是用来设计用户界面的,单击打开Main. ...
- EnjoyingSoft之Mule ESB开发教程第六篇:Data Transform - 数据转换
目录 1. 数据转换概念 2. 数据智能感知 - DataSense 3. 简单数据转换组件 3.1 Object to JSON 3.2 JSON to XML 3.3 JSON to Object ...
- 全网最贴心webpack系列教程和配套代码
webpack-demos:全网最贴心 webpack 系列教程和配套代码 欢迎关注个人技术博客:godbmw.com.每周 1 篇原创技术分享!开源教程(webpack.设计模式).面试刷题(偏前端 ...
- webpack 使用教程--实时刷新测试
学习webpack,基本始终是围绕: 1.如何安装webpack 2.如何使用webpack 3.如何使用loader 4.如何使用开发服务器 可能我们会在如何使用开发服务器的时候,遇到诸如调试的相关 ...
- 无废话ExtJs 入门教程十六[页面布局:Layout]
无废话ExtJs 入门教程十六[页面布局:Layout] extjs技术交流,欢迎加群(201926085) 首先解释什么是布局: 来自百度词典的官方解释:◎ 布局 bùjú: [distributi ...
- webpack入门级教程
Webpack是什么 首先可以看下官方文档,文档是最好的老师. 这里也有国外的一个朋友写的入门介绍. Webpack是由Tobias Koppers开发的一个开源前端模块构建工具.它的基本功能是将以模 ...
随机推荐
- 《k8s-1.13版本源码分析》- Scheduler启动前逻辑
本文原始地址(gitbook格式):https://farmer-hutao.github.io/k8s-source-code-analysis/core/scheduler/before-sche ...
- 在Salesforce成长:需要好奇心
今天的正题,今天谈谈好奇心和技术.这两天北大学霸Cherry分两次问了我两个问题,都触发了很好的结果和思考,让大家都受益. 第一天是她在做Salesforce和Flexible Report集成项目中 ...
- CASE 表达式
通过本篇文章我们来学习一下CASE表达式的基本使用方法. CASE表达式有简单 CASE表达式(simple case expression)和搜索 CASE表达式(searched caseexpr ...
- 一键解决更改计算机名后无法启动MSSQLSERVER服务问题
问题版本:SQL Server 2012. 解决办法:打开服务,Win + R运行services.msc,找到 SQL SERVER(MSSQLSERVER)服务右键->属性,切换至登录选项卡 ...
- WEB框架-Django框架学习-关联管理器(RelatedManager)
一.class RelatedManager "关联管理器"是在一对多或者多对多的关联上下文中使用的管理器.它存在于下面两种情况: 1.一对多 ForeignKey关系的“另一边” ...
- AI应用开发实战 - 定制化视觉服务的使用
AI应用开发实战 - 定制化视觉服务的使用 本篇教程的目标是学会使用定制化视觉服务,并能在UWP应用中集成定制化视觉服务模型. 前一篇:AI应用开发实战 - 手写识别应用入门 建议和反馈,请发送到 h ...
- linux shell 备注(一)
1.特殊字符 #!/bin/bash # $表示当前PID ID echo $$ # $n是shell脚本的参数,当0是第一个参数,即文件名 # $#是shell当前脚本的参数个数 # 例如:sh03 ...
- ReactNative之结合具体示例来看RN中的的Timing动画
今天继续更新RN相关的博客.上篇博客详细的聊了RN中关于Flex布局的相关东西,具体请参见<ReactNative之参照具体示例来看RN中的FlexBox布局>.本篇博客继续更新RN的动画 ...
- C# 三种打印方式含代码
一:C#代码直接打印pdf文件(打印质保书pdf文件) 引用: 代码注释很详细了. private void btn_pdf_Click(object sender, RoutedEventArgs ...
- 从一道面试题探究 Integer 的实现
记得有次面试,面试官问我: 如何写一个方法交换两个 Integer 类型的值? 当时心里一惊,这是把我当小白了呀!交换两个数的值还不容易么,最简单的直接搞一个中间变量,然后就可以交换了… … 面试官随 ...