【发布时间】:2018-12-09 07:55:31
【问题描述】:
我知道如果浏览器要渲染多个 JS 文件,这些文件里面显然有标识符,那么全局范围就会被这个标识符污染。我也知道避免这种情况的一种方法是使用模块,这些模块(在我的理解中)只是具有上述标识符作为成员的对象,因此有点模仿 C++ 命名空间。我也在学习 Node.js,并且有一个内置的模块系统可以简化这项任务,所以我的问题是:如何在发送到浏览器进行渲染的 js 文件中使用模块?
谢谢。
【问题讨论】:
标签: javascript
我知道如果浏览器要渲染多个 JS 文件,这些文件里面显然有标识符,那么全局范围就会被这个标识符污染。我也知道避免这种情况的一种方法是使用模块,这些模块(在我的理解中)只是具有上述标识符作为成员的对象,因此有点模仿 C++ 命名空间。我也在学习 Node.js,并且有一个内置的模块系统可以简化这项任务,所以我的问题是:如何在发送到浏览器进行渲染的 js 文件中使用模块?
谢谢。
【问题讨论】:
标签: javascript
browserify 和 WebPack 之类的工具正是您想要的(我个人更喜欢 browserify 而不是 WebPack)。看看this answer,它解释了你的很多顾虑。
在Node.JS 中,您可以使用module.exports 关键字导出模块,但您不能仅通过在<script> 标记中要求它们来在浏览器中导入这些模块。那是因为,浏览器不理解模块系统,并且一切都在全局 window 对象的上下文中工作,所以 module.exports 只是变成了 window.module.exports,我相信你不会想要的。因此,您可以使用 browserify 之类的工具将 Node.JS 脚本处理成您的浏览器可以理解的内容。
【讨论】:
这个问题通常由 module bundlers 或 module loader(例如 Webpack、Browserify、RequireJS)来解决。他们能够理解您的 JS 模块之间的关系,跳过未使用的模块并生成仅在您的浏览器中工作的输出。如果您遵循一些约定,所有这些都无需过多担心全局范围。
前段时间,在 ES6 之前,两种不同的方法被广泛使用:
CommonJS:
var module = require('my-module');
从 Node.js 广为人知
AMD:
define(['jquery'] , function ($) {
return function () {};
});
这适合浏览器使用,因为它在设计上支持模块的异步加载。
然后 ES6 引入了 native 对模块的支持:
import * as lib from 'lib';
Web 新技术的主要问题是您经常需要支持多种浏览器,这在很长一段时间内阻碍了开发人员使用新功能。如今,我们拥有代码转译器和复杂的代码捆绑器(例如 Webpack)。在他们的帮助下,您可以使用最新版本的语言,编译和捆绑您的代码,最后生成单个“bundle.js”文件,该文件支持旧版浏览器,但执行时间较慢。
【讨论】: