2020年6月,Angular 10发布,其中包含许多新功能和修复。实现的新功能之一是警告,当构建具有使用CommonJS模块打包的依赖项的应用程序时,将显示警告: 该警告的原因是,在执行生产构建时,使用CommonJS模块可能会导致更大的捆绑包大小。软件包大小的增加归因于CommonJS的设计方式,但我们稍后会详细介绍。如果您担心应用程序的性能并且使用的是CommonJS模块,那么您还有另一个选择:ES模块(EcmaScript模块)。 在本文中,我们将回顾您选择的模块格式化系统如何影响捆绑大小,CommonJS问题,ES模块如何解决这些问题以及在使用Wijmo时如何实现ES模块。 模块和包装尺寸模块是开发人员通过模块范围更好地组织变量和函数的一种方式。可以将模块作用域视为全局作用域。在模块范围内可用的变量和函数也可以由其他有权访问该模块范围的模块访问。 当其他模块可以使用某些东西时,这称为导出。创建导出后,其他模块可以导入该类,明确声明它们依赖于该变量,类或函数。 一旦您的应用程序可以在模块之间导入和导出变量和函数,就可以通过将应用程序分解为较小的块(为实现其功能而导入)来更轻松地组织应用程序。 由于变量和函数现在可以在多个文件中分解,因此您的应用程序现在需要在进行生产构建时将所有内容捆绑在一起。模块系统如何处理导入和导出功能,以及模块系统决定需要导入的内容,都会影响分发包的大小。 由于模块是如此有用,因此曾进行过多次尝试将模块/模块功能引入JavaScript。两种最受欢迎​​的模块系统是CommonJS和ES模块。 CommonJS和ES模块CommonJS是为JavaScript创建的模块格式化系统,该系统于2009年发布。从那时起,它已成为结构化和组织JavaScript代码的标准。该标准最初是为服务器端应用程序设计的,已极大地影响了NodeJS组织其模块管理的方式。 使用CommonJS,您可以定义模块,从中导出功能,以及使用require函数将其导入其他模块中。 例如,如果您有一个功能来验证可从其模块中导出的用户输入,则可以使用require函数使另一个模块可以访问它: - // verify.js
- exports.verifyInput = (userInput) => /* code implementation */
- // index.js
- const { verifyInput } = require(‘./verify.js’);
- …
- const validData = verifyInput(userInput);
复制代码由于verifyInput函数可以用作导出,因此我们现在可以使用index.js文件中的require方法导入该功能并加以利用。 由于CommonJS最初是为在服务器端应用程序上使用而创建的,因此在客户端应用程序上运行所带来的性能成本在服务器端应用程序上并不重要。但是,由于创建CommonJS时浏览器中缺少标准化的模块系统,因此它也成为JavaScript客户端库的流行模块格式系统。
由于客户端应用程序存在这些性能和优化问题,因此在创建ES模块时就考虑到了浏览器。导入和导出功能与CommonJS非常相似。而不是使用require导入变量和函数,而是使用import语句: - // verify.js
- exports.verifyInput => /* code implementation */
- // index.js
- import verifyInput from ‘./verify.js’;
- …
- const validData = verifyInput(userInput);
复制代码ES模块和CommonJS之间的最大区别在于模块的加载方式。CommonJS更动态,而ES模块更静态。
为了说明我的意思,当从另一个模块导入功能时,CommonJS允许您将变量传递到路径中,而ES模块则要求它是字符串文字: - // CommonJS
- const { verifyinput } = require(‘./${path}/verify.js’);
- // ES Modules
- import verifyInput from (‘./${path}/verify.js’); // Will not work
- import verifyInput from (‘./login/verify.js); // Will work
复制代码由于依赖项的加载方式,CommonJS可以采用这种动态方法。当CommonJS需要加载模块时,它是在运行时完成的。一次加载,实例化和评估模块。这就是允许您执行的操作,例如将变量传递到文件路径中(尽管这只是一个简单的示例)。由于此操作是在运行时完成的,因此使应用程序更难以执行树状摇动。 摇树是您的应用程序可以从文件中删除任何未使用的功能以缩小应用程序大小的时候。这些就像删除未使用的功能,注释和冗余空格。 因为CommonJS在运行时加载,实例化和评估所有对象,所以它使摇树变得更加困难,并且在发生时效率更低。之所以会发生摇晃的原因是因为webpack能够(在构建时)静态地了解我们从中导入的内容以及导出的内容。 ES模块没有同样的问题。由于ES模块比CommonJS更加静态,因此可以更静态地进行分析。进行的加载,实例化和评估分为三个不同的阶段,可以分别完成,而不是像CommonJS那样一起完成。这允许更有效的摇树。 在Wijmo中使用ES模块随着Wijmo 2020v2的发布,支持使用ES模块。默认情况下启用ES模块的使用,这意味着您无需采取任何措施即可使用ES模块。 从我们的测试中,您可以预期,包括Wijmo组件在内的组件的捆绑大小将减少大约30%。
您可以看到使用ES模块与使用Wijmo的CommonJS相比,捆绑包尺寸的细分情况如下: 请注意:如果希望继续在Wijmo中使用CommonJS模块,可以通过运行以下命令来完成: npm run wijmo-esm -- -disable 如果在使用wijmo-esm时遇到任何问题,还可以运行以下命令以获取更多信息: npm run wijmo-esm -- -help 要在生产模式下构建应用程序,您需要将以下命令添加到package.json文件的“脚本”部分: “prod": “ng build --prod",
然后,您可以通过运行npm run –prod来构建应用程序,并能够查看已创建的dist文件夹中的打包文件。
|