1、模块化

模块化已经是现代前端开发中不可或缺的一部分了

把复杂的问题分解成相对独立的模块,这样的设计可以降低程序复杂性,提高代码的重用,也有利于团队协作开发与后期的维护和扩展

ECMAScript2015 开始引入了模块的概念,我们称为:ECMAScript Module,简称:ESM

2、模块化的核心

  • 独立的作用域与依赖关系处理

    • 如何导出模块内部数据
    • 如果导入外部模块数据

3、基于 JavaScript 的模块系统分类

  • CommonJS(适用于服务端)
  • AMD/CMD
  • UMD
  • ESM - EcmaScript Module

4、ESM

ECMAScript2015/ECMAScript6 开始,JavaScript 原生引入了模块概念,而且现在主流浏览器也都有了很好的支持

4-1、独立模块作用域

一个文件就是模块,拥有独立的作用域,且导出的模块都自动处于 严格模式下,即:'use strict'

4-2、导出模块内部数据

使用 export 语句导出模块内部数据

// 导出单个特性
export let name1, name2, …, nameN;
export let name1 = …, name2 = …, …, nameN;
export function FunctionName(){...}
export class ClassName {...}// 导出列表
export { name1, name2, …, nameN };// 重命名导出
export { variable1 as name1, variable2 as name2, …, nameN };// 默认导出
export default expression;
export default function (…) { … }
export default function name1(…) { … }
export { name1 as default, … };// 模块重定向导出
export * from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;

4-3、导入外部模块数据

导入分为两种模式

  • 静态导入
  • 动态导入

静态导入

在浏览器中,import 语句只能在声明了 type="module" 的 script 的标签中使用。

import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

静态导入方式不支持延迟加载,import 必须这模块的最开始

document.onclick = function () {// import 必须放置在当前模块最开始加载// import m1 from './m1.js'// console.log(m1);}

动态导入

此外,还有一个类似函数的动态 import(),它不需要依赖 type="module" 的 script 标签。

关键字 import 可以像调用函数一样来动态的导入模块。以这种方式调用,将返回一个 promise

import('./m.js').then(m => {//...
});
// 也支持 await
let m = await import('./m.js');

通过 import() 方法导入返回的数据会被包装在一个对象中,即使是 default 也是如此

5、其它模块化系统方案

  • CommonJS
  • AMD
  • UMD
  • ESM

无论是那种模块化规范,重点关注

  • 独立模块作用域
  • 导出模块内部数据
  • 导入外部模块数据

5-1、CommonJS

在早起前端对于模块化并没有什么规范,反而是偏向服务端的应用有更强烈的需求,CommonJS 规范就是一套偏向服务端的模块化规范,NodeJS 就采用了这个规范。

独立模块作用域

一个文件就是模块,拥有独立的作用域

导出模块内部数据

通过 module.exportsexports 对象导出模块内部数据

// a.js
let a = 1;
let b = 2;module.exports = {x: a,y: b
}
// or
exports.x = a;
exports.y = b;

导入外部模块数据

通过 require 函数导入外部模块数据

// b.js
let a = require('./a');
a.x;
a.y;

5-2、AMD

因为 CommonJS 规范一些特性(基于文件系统,同步加载),它并不适用于浏览器端,所以另外定义了适用于浏览器端的规范

AMD(Asynchronous Module Definition)

https://github.com/amdjs/amdjs-api/wiki/AMD

浏览器并没有具体实现该规范的代码,我们可以通过一些第三方库来解决

5-2-1、requireJS

https://requirejs.org/

// 1.html
<script data-main="scripts/main" src="https://cdn.bootcss.com/require.js/2.3.6/require.min.js"></script>

独立模块作用域

通过一个 define 方法来定义一个模块,并通过该方法的第二个回调函数参数来产生独立作用域

// scripts/Cart.js
define(function() {// 模块内部代码
})

导出模块内部数据

通过 return 导出模块内部数据

// scripts/Cart.js
define(function() {return class Cart {add(item) {console.log(`添加商品:${item}`)}}
})

导入外部模块数据

通过前置依赖列表导入外部模块数据

// scripts/main.js
// 定义一个模块,并导入 ./Cart 模块
define(['./Cart'], function(Cart) {let cart = new Cart()cart.add({name: 'iphoneXX', price: 1000000})
})

5-2-2、requireJSCommonJS 风格

require.js 也支持 CommonJS 风格的语法

导出模块内部数据

// scripts/Cart.js
define(['require', 'exports', 'module'], function(require, exports, module) {class Cart {add(item) {console.log(`添加商品:${item}`)}}exports.Cart = Cart;
})
// 忽略不需要的依赖导入
define(['exports'], function(exports) {class Cart {add(item) {console.log(`添加商品:${item}`)}}exports.Cart = Cart;
})
// 如果是依赖的导入为:require, exports, module,也可以省略依赖导入声明
define(function(require, exports, module) {class Cart {add(item) {console.log(`添加商品:${item}`)}}exports.Cart = Cart;
})

导入外部模块数据

// scripts/main.js
define(['./Cart'], function(Cart) {let cart = new Cart()cart.add({name: 'iphoneXX', price: 1000000})
})

5-3、UMD

严格来说,UMD 并不属于一套模块规范,它主要用来处理 CommonJSAMDCMD 的差异兼容,是模块代码能在前面不同的模块环境下都能正常运行

(function (root, factory) {if (typeof module === "object" && typeof module.exports === "object") {// Node, CommonJS-likemodule.exports = factory(require('jquery'));}else if (typeof define === "function" && define.amd) {// AMD 模块环境下define(['jquery'], factory);}
}(this, function ($) { // $ 要导入的外部依赖模块$('div')// ...function b(){}function c(){}// 模块导出数据return {b: b,c: c}
}));

webpack

文章目录

    • 1、模块化
    • 2、模块化的核心
    • 3、基于 JavaScript 的模块系统分类
    • 4、ESM
      • 4-1、独立模块作用域
      • 4-2、导出模块内部数据
      • 4-3、导入外部模块数据
    • 5、其它模块化系统方案
      • 5-1、CommonJS
      • 5-2、AMD
        • 5-2-1、requireJS
        • 5-2-2、`requireJS` 的 `CommonJS` 风格
      • 5-3、UMD
  • webpack
    • 1、webpack 是什么?
    • 2、安装
    • 3、使用
    • 4、打包模块
      • 4-1、入口文件
      • 4-2、打包命令
    • 5、打包配置
    • 6、核心配置
      • 6-1、mode
      • 6-2、entry
      • 6-3、output
    • 7、深入
      • 7-1、执行简要流程
    • 8、Loaders
      • 8-1、raw-loader
      • 8-2、file-loader
      • 8-3、url-loader
      • 8-4、css-loader
      • 8-5、style-loader
  • webpack
    • 1、Plugins
      • 1-2、HtmlWebpackPlugin
      • 1-3、clean-webpack-plugin
      • 1-4、mini-css-extract-plugin
    • 2、sourceMap
    • 3、WebpackDevServer
      • 3-1、Proxy
      • 3-2、Hot Module Replacement

1、webpack 是什么?

  • 官⽅方⽹网站:https://webpack.js.org/
  • 中⽂文⽹网站:https://www.webpackjs.com/

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

2、安装

webpack 是一个使用 Node.js 实现的一个模块化代码打包工具。所以,我们需要先安装 webpack,安装之前需要搭建好 Node.js 环境

 npm install -D webpack webpack-cli

注:不推荐全局安装

webpack-cli : 提供 webpack 命令、工具,类似 create-react-app

webpack : webpack 代码,类似 react

3、使用

./node_modules/.bin/webpack// 查看版本
./node_modules/.bin/webpack -v

也可以编辑 package.jsonscripts 来简化输入

// package.json
{...,"scripts": {"start": "webpack"   // scripts 中可以定位到 ./node_modules/.bin/ 目录下}
}

scripts 中使用 teststartrestartstop 命名的时候,可以在调用的时候省略 run,即直接 npm start

当然,还可以使用更加方便的方式:

npx webpack

通过 npx 也可以帮助我们定位命令到 ./node_modules/.bin/ 目录下

注:npm5.2+ 增加,如果没有,可以使用 npm i -g npx 来安装

4、打包模块

打包之前,我们需要了解一个概念,入口文件

4-1、入口文件

入口文件就是我们项目中加载的第一个文件,比如上面的 main.js 文件,其它文件都是通过 import 等方式引入的,webpack 会从我们指定的入口文件开始分析所有需要依赖的文件,然后把打包成一个完整文件。

4-2、打包命令

webpack ./js/index.js

上面命令会使用 webpack 默认的一些配置对模块文件进行打包,并把打包后的文件输出到默认创建的 ./dist 目录下,打包后的文件名称默认为 main.js

模块文件打包以后,就可以在不支持 es6 模块语法的浏览器环境下引入使用了。

打包文件分析

  • 把分散的模块文件打包到一个文件中,不需要外部引入了
  • 内置了一个小型模块加载器(类似 requireJS),实现了打包后的代码隔离与引用

以上就是 webpack 最基础的使用于基本原理,当然强大的 webpack 远远不止这些功能。

5、打包配置

虽然,我们可以直接通过命令的来打包,但是推荐创建一个 webpack.config.js 的配置文件来实现更方便和强大的功能。

webpack 命令在运行的时候,默认会读取运行命令所在的目录下的 webpack.config.js 文件,通常我们会在项目的根目录下运行命令和创建配置文件。

我们也可以通过 —config 选项来指定配置文件路径:

webpack --config ./configs/my_webpack.config.js

通常情况下,我们的项目目录大致如下:

/
-- /dist - 项目打包后存放目录
-- /node_modules - 第三方模块
-- /src
------ css/
------ images/
------ js/
------ index.js
-- webpack.config.js
-- package.json

配置文件

module.exports = {...   //配置项
}

6、核心配置

6-1、mode

模式 : "production" | "development" | "none"

不同的模式会对 webpack 打包的时候进行一些对应的优化配置。

module.exports = {mode: 'production'
}

6-2、entry

指定打包⼊口⽂文件,有三种不同的形式:string | object | array

module.exports = {entry: './src/index.js'
}
module.exports = {entry: ['./src/index1.js','./src/index2.js',]
}
module.exports = {entry: {'index1': "./src/index1.js",'index2': "./src/index2.js"}
}

6-3、output

打包后的文件位置

module.exports = {...,output: {path: path.resolve(__dirname, "dist"),filename: "bundle.js",filename: "[name].js"}
}
  • 可以指定一个固定的文件名称,如果是多入口多出口(entry 为对象),则不能使用单文件出口,需要使用下面的方式
  • 通过 webpack 内置的变量占位符:[name]

7、深入

webpack 中,有一个很重要的特性:模块不仅仅只是 js 的文件,webpack 可以把任意文件数据作为模块进行处理,包括:非 js 文本、css、图片等等

import txt from './a.txt';
console.log(txt);

但是 webpack 默认情况下只能处理 js 模块,如果需要处理其它类型的模块,则需要使用它提供的一些其它功能

7-1、执行简要流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Wzljt7X-1645613635143)(./assets/workflow.png)]

  • loaderswebpack 中灰常核心的内容之一,前面我们说的非 js 类型的模块处理就靠它了。webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。
  • pluginswebpack 中另外一个核心的内容,它主要是扩展 webpack 本身的一些功能。插件可以运行在 webpack 的不同阶段(钩子 / 生命周期)。

8、Loaders

https://webpack.js.org/loaders/

module.exports = {...,module: {rules:[{test:/\.xxx$/,use:{loader: 'xxx-load'}}]}
}

webpack 碰到不识别的模块的时候,webpack 会在配置的 module 中进行该文件解析规则的查找

  • rules 就是我们为不同类型的文件定义的解析规则对应的 loader,它是一个数组
  • 每一种类型规则通过 test 选项来定义,通过正则进行匹配,通常我们会通过正则的方式来匹配文件后缀类型
  • use 针对匹配到文件类型,调用对应的 loader 进行处理

从一个简单的案例来了解 loader

我是 txt 的内容
# 我是 md 的内容
import txtData from './datas/data.txt';
import mdData from './datas/data.md';console.log('txtData: ', txtData);
console.log('mdData: ', mdData);

默认情况下,webpack 会报错,因为 webpack 处理不了 txt 和 md 这样的非 js 的模块,但是我们可以通过专门来处理纯文本内容(不同的 loader 有不同的作用)

8-1、raw-loader

在 webpack 中通过 import 方式导入文件内容,loader 并不是 webpack 内置的,所以首先要安装

npm install --save-dev raw-loader

然后在 webpack.config.js 中进行配置

module.exports = {...,module: {rules: [{test: /\.(txt|md)$/,use: 'raw-loader'}]}
}

8-2、file-loader

把识别出的资源模块,移动到指定的输出⽬目录,并且返回这个资源在输出目录的地址(字符串)

npm install --save-dev file-loader
rules: [...,{test: /\.(png|jpe?g|gif)$/,use: {loader: "file-loader",options: {// placeholder 占位符 [name] 源资源模块的名称// [ext] 源资源模块的后缀name: "[name]_[hash].[ext]",//打包后的存放位置outputPath: "./images",// 打包后文件的 urlpublicPath: './images',}}}
]

占位符:https://webpack.js.org/loaders/file-loader#placeholders

8-3、url-loader

可以处理理 file-loader 所有的事情,但是遇到图片格式的模块,可以选择性的把图片转成 base64 格式的字符串,并打包到 js 中,对⼩体积的图片⽐较合适,⼤图⽚不合适。

npm install --save-dev url-loader
rules: [...,{test: /\.(png|jpe?g|gif)$/,use: {loader: "url-loader",options: {// placeholder 占位符 [name] 源资源模块的名称// [ext] 源资源模块的后缀name: "[name]_[hash].[ext]",//打包后的存放位置outputPath: "./images"// 打包后文件的 urlpublicPath: './images',// 小于 100 字节转成 base64 格式limit: 100}}}
]

8-4、css-loader

分析 css 模块之间的关系,并合成⼀个 css

npm install --save-dev css-loader
rules: [...,{test: /\.css$/,use: {loader: "css-loader",options: {// 启用/禁用 url() 处理url: true,// 启用/禁用 @import 处理import: true,// 启用/禁用 SourcemapsourceMap: false}}}
]

8-5、style-loader

css-loader 生成的内容,用 style 标签挂载到⻚面的 head

npm install --save-dev style-loader
rules: [...,{test: /\.css$/,use: ["style-loader", "css-loader"]}
]

同一个任务的 loader 可以同时挂载多个,处理顺序为:从右到左,也就是先通过 css-loader 处理,然后把处理后的 css 字符串交给 style-loader 进行处理

rules: [...,{test: /\.css$/,use: [{loader: 'style-loader',options: {}},'css-loader']}
]

webpack

文章目录

    • 1、模块化
    • 2、模块化的核心
    • 3、基于 JavaScript 的模块系统分类
    • 4、ESM
      • 4-1、独立模块作用域
      • 4-2、导出模块内部数据
      • 4-3、导入外部模块数据
    • 5、其它模块化系统方案
      • 5-1、CommonJS
      • 5-2、AMD
        • 5-2-1、requireJS
        • 5-2-2、`requireJS` 的 `CommonJS` 风格
      • 5-3、UMD
  • webpack
    • 1、webpack 是什么?
    • 2、安装
    • 3、使用
    • 4、打包模块
      • 4-1、入口文件
      • 4-2、打包命令
    • 5、打包配置
    • 6、核心配置
      • 6-1、mode
      • 6-2、entry
      • 6-3、output
    • 7、深入
      • 7-1、执行简要流程
    • 8、Loaders
      • 8-1、raw-loader
      • 8-2、file-loader
      • 8-3、url-loader
      • 8-4、css-loader
      • 8-5、style-loader
  • webpack
    • 1、Plugins
      • 1-2、HtmlWebpackPlugin
      • 1-3、clean-webpack-plugin
      • 1-4、mini-css-extract-plugin
    • 2、sourceMap
    • 3、WebpackDevServer
      • 3-1、Proxy
      • 3-2、Hot Module Replacement

1、Plugins

扩展 webpack 本身的一些功能,它们会运行在 webpack 的不同阶段(钩子 / 生命周期)。

1-2、HtmlWebpackPlugin

在打包结束后,⾃动生成⼀个 html ⽂文件,并把打包生成的 js 模块引⼊到该 html

npm install --save-dev html-webpack-plugin
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {...plugins: [new HtmlWebpackPlugin({title: "My App",filename: "app.html",template: "./src/html/index.html"}) ]
};
<!--./src/html/index.html-->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body><h1>html-webpack-plugin</h1>
</body>
</html>

html 模板中,可以通过 <%=htmlWebpackPlugin.options.XXX%> 的方式获取配置的值

更多的配置

  • title: ⽤来生成⻚面的 title 元素
  • filename: 输出的 HTML ⽂件名,默认是 index.html, 也可以直接配置子目录
  • template: 模板⽂件路径,⽀持加载器(loader),⽐如 html!./index.html
  • inject: true | 'head' | 'body' | false,注⼊所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素中
  • favicon: 添加特定的 favicon 路径到输出的 HTML 文件中
  • minify: {} | false, 传递 html-minifier 选项给 minify 输出
  • hash: true | false,如果为 true,将添加 webpack 编译生成的 hash 到所有包含的脚本和 CSS ⽂件,对于解除 cache 很有用
  • cache: true | false,如果为 true,这是默认值,仅在文件修改之后才会发布文件
  • showErrors: true | false,如果为 true,这是默认值,错误信息会写入到 HTML ⻚面中
  • chunks: 允许只添加某些块 (⽐如,仅 unit test 块)
  • chunksSortMode: 允许控制块在添加到⻚面之前的排序方式,⽀持的值:'none' | 'default' |{function}-default:'auto'
  • excludeChunks: 允许跳过某些块,(⽐如,跳过单元测试的块)

1-3、clean-webpack-plugin

删除(清理)构建目录

npm install --save-dev clean-webpack-plugin
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {...plugins: [...,new CleanWebpackPlugin(),...]
}

1-4、mini-css-extract-plugin

提取 CSS 到一个单独的文件中

npm install --save-dev mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {...,module: {rules: [{test: /\.s[ac]ss$/,use: [{loader: MiniCssExtractPlugin.loader},'css-loader','sass-loader']}]},plugins: [...,new MiniCssExtractPlugin({filename: '[name].css'}),...]
}

2、sourceMap

我们实际运行在浏览器的代码是通过 webpack 打包合并甚至是压缩混淆过的代码,所生成的代码并不利于我们的调试和错误定位,我们可以通过 sourceMap 来解决这个问题,sourceMap 本质是一个记录了编译后代码与源代码的映射关系的文件,我们可以通过 webpackdevtool 选项来开启 sourceMap

module.exports = {mode: 'production',devtool: 'source-map',...
}

首先,编译后会为每一个编译文件生成一个对应的 .map 文件,同时在编译文件中添加一段对应的 map 文件引入代码

...
//# sourceMappingURL=xx.js.map
...
/*# sourceMappingURL=xx.css.map*/

同时,现代浏览器都能够识别 sourceMap 文件,如 chrome,会在 Sources 面板中显示根据编译文件与对应的 map 文件定位到源文件中,有利于我们的调试和错误定位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fbq0QNuW-1645613657020)(./assets/source_map.png)]

3、WebpackDevServer

每次的代码修改都需要重新编译打包,刷新浏览器,特别麻烦,我们可以通过安装 webpackDevServer 来改善这方面的体验

npm install --save-dev webpack-dev-server

启动命令:

npx webpack-dev-server

或者,package.json 中添加 scripts

...,
"scripts": {"server": "webpack-dev-server"
}

修改 webpack.config.js

module.exports = {...,devServer: {// 扩展的虚拟路径contentBase: "./abc",// 自动开启浏览器open: true,// 端口port: 8081}
}

启动服务以后,webpack 不在会把打包后的文件生成到硬盘真实目录中了,而是直接存在了内存中(同时虚拟了一个存放目录路径),后期更新编译打包和访问速度大大提升

3-1、Proxy

当下前端的开发都是前后端分离开发的,前端开发过程中代码会运行在一个服务器环境下(如当前的 WebpackDevServer),那么在处理一些后端请求的时候通常会出现跨域的问题。WebpackDevServer 内置了一个代理服务,通过内置代理就可以把我们的跨域请求转发目标服务器上(WebpackDevServer 内置的代理发送的请求属于后端 - node,不受同源策略限制),具体如下:

const Koa = require('koa');
const KoaRouter = require('koa-router');const app = new Koa();
const router = new KoaRouter();router.get('/api/info', async ctx => {ctx.body = {username: 'zMouse',gender: 'male'}
})app.use( router.routes() );
app.listen(8787);
axios({url: 'http://localhost:8787/api/info'
}).then(res => {console.log('res',res.data);
})

默认情况下,该代码运行以后会出现跨域请求错误,修改 webpack 配置

module.exports = {...,devServer: {// 生成的虚拟目录路径contentBase: "./dist",// 自动开启浏览器open: true,// 端口port: 8081,proxy: {'/api': {target: 'http://localhost:8787'}}}
}

通过 proxy 设置,当我们在当前 WebpackDevServer 环境下发送以 /api 开头的请求都会被转发到 http://localhost:8787 目标服务器下

axios({//url: 'http://locahost:8081/api/info',url: '/api/info'
}).then(res => {console.log('res',res.data);
})

注意 url 地址要填写 WebpackDevServer 域,比如当前 WebpackDevServer 开启的是 http://localhost:8081,也就是我们当前前端代码运行的环境,那么请求的 url 也必须发送到这里,当我们的请求满足了 proxy 中设置的 /api 开头,那么就会把请求转发到 target ,所以最后的实际请求是:http://lcoahost:8787/api/info

3-2、Hot Module Replacement

在之前当代码有变化,我们使用的 live reload,也就是刷新整个页面,虽然这样为我们省掉了很多手动刷新页面的麻烦,但是这样即使只是修改了很小的内容,也会刷新整个页面,无法保持页面操作状态。HMR 随之就出现了,它的核心的局部(模块)更新,也就是不刷新页面,只更新变化的部分

module.exports = {...,devServer: {// 生成的虚拟目录路径contentBase: "./dist",// 自动开启浏览器open: true,// 端口port: 8081,// 开启热更新hot:true,// 即使 HMR 不生效,也不去刷新整个页面(选择开启)hotOnly:true,proxy: {'/api': {target: 'http://localhost:8787'}}}
}

开启 HMR 以后,当代码发生变化,webpack 即会进行编译,并通过 websocket 通知客户端(浏览器),我们需要监听处理来自 webpack 的通知,然后通过 HMR 提供的 API 来完成我们的局部更新逻辑

export default function() {console.log('start1!');
}
import fn1 from './fn1.js';
box1.onclick = fn1;if (module.hot) {//如果开启 HMRmodule.hot.accept('./fn1.js', function() {// 更新逻辑box1.onclick = fn1;})
}

上面代码就是 当 ./fn1.js 模块代码发生变化的时候,把最新的 fn1 函数绑定到 box1.onclick 上

从上面就可以看到,HMR 其实就是以模块为单位,当模块代码发生修改的时候,通知客户端进行对应的更新,而客户端则根据具体的模块来更新我们的页面逻辑(这些逻辑需要自己去实现),好在当前一些常用的更新逻辑都有了现成的插件

css热更新

样式热更新比较简单,style-loader 中就已经集成实现了,我们只需要在 use 中使用就可以了

react 热更新

  • https://github.com/gaearon/react-hot-loader

  • react 脚手架中也有集成

vue 热更新

  • https://github.com/vuejs/vue-loader
  • vue 脚手架中也有集成

webpack—模块化、模块化核心、ESM、其它模块化|概念、安装、使用、打包模块、打包配置、核心配置、深入、Loaders、||Plugins、sourceMap、WebpackDevServer、相关推荐

  1. 前端模块化(CMJ和ESM)

    1. 为什么要模块化 把具有不同功能的版块封装为不同的模块,比如把涉及到网络请求的函数全都写在一个network.js文件里,把一些工具类的函数写在tool.js文件里,框架里的每一个组件都占据一个. ...

  2. 指定模块打包命令_大前端进阶之Babel、模块化、webpack

    Babel 什么是Babel? 很多ES6高级语法浏览器是不支持的,Node.js也不一定能够运行,这时就需要使用转码器了. Babel是一个使用非常广泛的转码器,它可以将ES6语法代码转换为ES5语 ...

  3. JS 模块化: CommonJS 与 ESM(ECMAScript Module) 的引用机制比较 循环依赖解决方式

    JS 模块化: CommonJS 与 ESM(ECMAScript Module) 的引用机制比较 & 循环依赖解决方式 文章目录 JS 模块化: CommonJS 与 ESM(ECMAScr ...

  4. osgi 模块化_OSGi案例研究:模块化vert.x

    osgi 模块化 OSGi使Java代码可以清晰地划分为多个模块,这些模块称为捆绑软件 ,可以访问由每个捆绑软件的类加载器控制的代码和资源. OSGi 服务提供了一种附加的分离机制:接口的用户无需依赖 ...

  5. 什么是前端模块化?为什么要进行模块化开发?前端技术文章分享

    之前文章都分享的Java相关,今天就分享一篇前端技术文章,一起来看看今日前端技术文章吧~希望能够帮助到你! 模块化是一种软件开发的设计模式,它将一个大型的软件系统划分成多个独立的模块,每个模块都有自己 ...

  6. c语言是结构化 模块化,c语言是完全模块化和结构化的语言,怎么理解,什么是模块化和结构化...

    满意答案 佩佩韩衣吧 2013.06.12 采纳率:55%    等级:12 已帮助:29322人 所谓模块化,简单的理解,就是说你的程序是由相互之间相对独立的模块组成.那么具体的说,一个稍微大一点的 ...

  7. Node.js模块化开发||Node.js中模块化开发规范

    JavaScript开发弊端 a.js b.js JavaScript在使用时存在两大问题,文件依赖和命名冲突. 生活中的模块化开发 软件中的模块化开发 app.j user.一个功能就是一个模块,多 ...

  8. nacos 本地测试_微服务架构系列之Nacos 配置核心概念

    上次讲了<微服务架构之Nacos配置中心之配置MySQL数据库>,本次讲述Nacos 配置核心概念.原作者:哈喽沃德先生,谢谢关注哈喽沃德先生. 1.配置 为什么需要配置?概念. 在系统开 ...

  9. 为何webpack风靡全球?三大主流模块打包工具对比

    小编说:前端项目日益复杂,构建系统已经成为开发过程中不可或缺的一个部分,而模块打包(module bundler)正是前端构建系统的核心.Webpack能成为最流行的打包解决方案,并不是偶然.webp ...

  10. 【模块打包工具】Webpack

    Webpack的出现 使得 前端模块化的范围扩大了许多 以前 只是 JS 模块化 而现在 是 前端模块化 包括 样式 图片 字体等所有的资源模块化 核心特性 1.可以通过webpack 模块打包器 b ...

最新文章

  1. linux如何编译tex,Linux下优秀的文本编辑器(Markdown、LaTeX、MathJax)
  2. 新一届最强预训练模型上榜,出于BERT而胜于BERT
  3. 2.Spring初学
  4. 怎么画正五边形步骤_每个药店必备三伏贴的POP海报,我教你画
  5. python导入xlsx文件-python怎么用pd导入xlsx
  6. Gateway网关-过滤器链执行顺序
  7. 毫米波雷达数据处理_基于毫米波雷达的桥梁静挠度采集系统
  8. mybatis里oracle与MySQL的insert_update
  9. python实现多语言语种识别_用Python进行语言检测
  10. 配置Apache Httpd Server 2.2 Virtual Host UrlRewrite
  11. Swift语言指南(一)--语言基础之常量和变量
  12. PAT (Basic Level) Practise (中文)- 1002. 写出这个数 (20)
  13. -函数-MATLAB提供的函数/主子函数/匿名-嵌套函数
  14. Android中的Intent详细讲解【转】
  15. 那些在开发中用到的正则表达式
  16. java 异或表示状态
  17. 吴伯凡-认知方法论-为什么说“盲维”是认知升级的重要概念
  18. 站在巨人的肩膀上—英语
  19. 二十一世纪的计算研讨会及启示
  20. 午夜分享女人的绝对隐私

热门文章

  1. 【控制工程】与控制工程密切相关的拉普拉斯变换
  2. 7系列高速收发器简介 GTP IP核
  3. 旭荣管理软件怎么修改小票内容_美萍超市管理软件——让管理回归轻松
  4. 《机器视觉算法与应用》第3章 机器视觉算法之模板匹配——学习笔记
  5. 其他干货——如何做科学报告(oral, poster, eLightning)
  6. idea设置主题路径
  7. SOLIDWORDS API修改零部件属性全部保存
  8. 一文看懂NXP汽车电机控制解决方案(NXP整理)
  9. 汽车软件质量体系DIY(1)难题-价值-周期
  10. 全球人工智能发展白皮书