- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
本文分享自华为云社区《JS/TS项目里的Module都是什么?都有几种形式?loaders和bundlers的区别是什么?》,作者: gentle_zhou 。
在日常进行JS/TS项目开发的时候,经常会遇到require
某个依赖和module.exports
来定义某个函数的情况。再加上在日常审视代码的时候,发现tsconfig.json文件里有一个"compilerOptions"
,里面关于module引入的是"commonjs"
,就很好奇Modules
都代表什么和有什么作用呢。
本文会分为如下几个部分进行介绍:什么是Module?;为什么我们需要Modules?;几种常见的Module形式;Module loaders和Module bundlers的区别;参考链接。
一个Module(模块)顾名思义就是一段可以重复利用的代码(通常是一个特性,或则一些特性的集合;可以是一个文件或则多个文件/文件夹的集合),它封装了内部代码实现的细节并曝露一个公开的API,让其他代码可以轻易地加载和使用。
技术上来说,其实完成一个JS/TS项目,我们并不需要模块,直接上手写代码也是可以的。但就像在JAVA、Python软件项目里,不引入依赖一样,会导致程序员们重复写很多相同的代码。
引入Module,为的就是可以应对JS/TS项目的代码越来越庞大,越来越复杂的情形。我们需要使用软件工程的方法,来管理JS/TS项目的业务逻辑。
在JS/TS项目中,模块应该允许我们实现以下功能:
在 ES6 Module 出现之前,在ES5时期,JS并没有提供一个官方的定义模块的规则;因此JavaScript 社区里的天才程序员们尝试了各种形式来定义模块,以达到“在现有的运行环境下,可以实现模块效果”的目的。
一些非常有名的模块形式:
require
和module.exports
就是CommonJS里用来定义依赖和模块的:var dep1 = require('./dep1');
module.exports = function(){ // ...}
define函数
来定义模块:// 一个依赖数组&一个工厂函数以参数的形式调用define函数
define(['dep1', 'dep2'], function (dep1, dep2) {
//通过返回一个值来定义模块值
return function () {};
});
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. 以同步模块的方式注册.
define(['b'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node节点. 不能和严格意义上的CommonJS一起使用,但是类似CommonJS的环境里是支持使用module.expoerts的,就像node.
module.exports = factory(require('b'));
} else {
// 浏览器 globals (根节点是window)
root.returnExports = factory(root.b);
}
}(this, function (b) {
// 返回一个值来定义module export;这里返回的是一个对象,但是模块其实可以返回一个函数作为exported value.
return {};
}));
以及现在出现的官方ES6 模块形式,一种原生的模块形式。它用export来输出模块的公开API:
// 输出函数
export function sayHello(){
console.log('Hello');
}
我们可以使用import和as来引入部分代码到模块里:
import { sayHello as say } from './lib';
say(); // 输出Hello
或则直接在一开始引入整个模块:
import * as lib from './lib';
lib.sayHello(); // 输出 Hello
两者都是为了让我们编写模块化JS/TS应用的时候更方便快捷。
模块加载器用来解析并加载以特定模块格式编写的模块,通常是一些库;可以加载、解释和执行使用特定模块格式/语法定义的JavaScript模块,比如AMD或CommonJS。
在编写模块化JS/TS应用程序时,通常每个模块都有一个文件。因此,当编写由数百个模块组成的应用程序时,要确保所有文件都以正确的顺序包含进去可能会非常痛苦。所以,如果有加载器会为你负责依赖管理,确保所有模块在应用程序执行时被加载,那会轻松容易很多。
模块加载器是在运行时(runtime)运行的:
如果你试着在浏览器的开发人员控制台中打开network选项卡,将看到许多文件是按需由模块加载器加载的:
一些流行的模块加载器的例子如下:
模块绑定器相当于是模块加载器的替代品;基本上,它们做的事情是一样的(管理和加载相互依赖的模块)。
但模块绑定器和加载器不同的地方是,它并非是在运行时运行的,而是作为应用程序构建的一部分运行(在build的时候运行);而且它是在浏览器中加载的。因此,绑定器在执行代码之前会将所有模块合并到一个文件/bundle中(比如叫bundle.js),而不是在代码运行时再去加载出现的依赖项。比如现在流行的两个bundlers:Webpack(AMD,CommonJS, es6模块的bundler)和Browserify(CommonJS模块的bundler)。
这个问题的答案取决于JS/TS应用程序的结构与大小。
使用bundler的主要优点是,它让浏览器需要下载的文件变少了很多,这可以给我们的应用程序带来性能上的优势(因为减少了加载所需的时间);但是取决于应用程序的模块数量,并不是说用bundler就一定是最好的。对于那种大型应用(有很多模块),模块加载器可以提供更好的性能,因为bundler在一开始加载一个巨大的单文件会阻碍应用的启动。
如何选取,其实只需要我们进行测试比较一下即可~
我有一个设计。我在这里遇到一个问题。 我要做的是,我必须显示前 3 个 li 标签的 100% 宽度,并保留 li 标签的 33.33%。 这是我的预期输出 li-100% width li-100%
用例: 对于我的 angularJS(1.6.4) 应用程序,我正在用 jasmine 编写单元测试。 在我的测试用例中,我调用了一个 poll() 函数,该函数使用 $interval 反复调用另一
如何在 hookdisplayTop 中获取当前产品? 这是我确保我在“产品”页面中的当前方式: if ( Dispatcher::getInstance()->getController() ==
我有一个带有“li”-s 的导航菜单。我想像这样把这个 li 变成六 Angular 形: 我该怎么做? 最佳答案 我会使用带边框的伪元素。 * { margin: 0; paddin
我是 JQuery 的新手。我试图基本上允许访问者在我的网站上的两种颜色主题之间进行选择。当他们单击浅色主题的链接时,除了我的导航菜单中的各种元素外,所有内容都会按预期改变颜色。这是 JQuery:
所以我试图在我的 Accordion 中的一些文本下面实现一个日期。 文本和图像由用户插入到 wordpress 的文章部分,日期应始终显示在文本下方。但是一直报错,一直在1970。 下面的代码:
我需要在一段时间内将测试数据提供给 Swing 间隔。数据集需要很长时间才能解析,所以我使用 SwingWorker 在后台解析它。在将数据馈送到 GUI 时(例如,每秒一个项目),我可以从 Swin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 prev next function showPage(page) { var listItems =
里?
我有一个小程序,其中有冰淇淋口味列表,计算机使用“console.log();”打印一个句子和味道。我已经开始了这个项目,它看起来像这样: var randomFlavour = Math.rando
我想创建自定义 toast,其中一个 View 有点脱离父 View 。所以我做了这样的事情 这是我定制的 toast round_button.xml
在过去的 6 个月里,我一直在从 repl 运行我的 Clojure 应用。 也就是说,每当我想运行该应用程序时,我都会加载一个 clojure repl,然后输入:(load-file "src/r
我想在我的网页的整个主体周围添加一个边框。 我创建了一个布局,其中包含一个主体,其中包含多个 div 标签。我添加了我认为会在所有内容周围放置边框的 CSS。不幸的是,出于某种原因,我布局中的最后两个
我有一个无序列表 (ul),我正在尝试制作 3 列。当我有 4 个 li's 时,它只显示 2 列。我怎样才能让它有 3 列和 4 个 li ? 此外,我希望 li 从左到右,而不是从上到下,如下所示
我目前正在使用 JPA 创建一个批处理,其层次结构为 Tasklet-> 访问器-> 服务-> 处理器,并且我正在使用 Glassfish 作为我的数据库。但当我运行时` [ERROR] [com.a
到目前为止我有这个: $(".actor ul li").not($(".actor ul li").slice(0,11)).hide(); 我还想从 hide() 中排除最后一个 li。我该怎么做
我必须使用 tools.jar 中的库并因此添加了此依赖项: com.sun tools 1.6.0 system ${java.home}/../lib/t
if(BrowserDetect.browser=="safari"){document.write('')} 我可以在 html 文档的底部放置条件注释吗? (在体内)还是应该在头部? 就页面速度
我是一名优秀的程序员,十分优秀!