如何从非模块文件中使用js模块

How to use js modules from non-module files

我是 js 模块的初学者。

我正在开发一个相当简单的 Web 应用程序。它使用 typescript 和 angular 2,后者严重依赖于模块。

我的大部分应用 ts 文件 'import' 一个或多个 js 模块(通常主要是 angular 2 个模块)。

据我了解,因为我的应用程序 ts 文件具有顶级 'import',它们会被 typescript 自动视为 js 模块。

但是,我希望我的任何其他应用程序 ts 文件都可以访问我的任何应用程序 ts 文件,而不必 'import' 彼此。但是因为它们现在本身就是模块,ts 要求我这样做...

可能吗?

对于我的每个应用程序 ts 文件,我都必须声明其中使用的所有其他应用程序 ts 文件,这对我来说似乎很疯狂(我喜欢只有一个 class/interface).此外,这依赖于相对路径,一旦我重组我的文件夹结构就会中断。

我是不是想错了?

Is it possible

绝非易事。 ts 文件是一个模块并使用例如module.exports(如果是 commonjs)需要填充。这只是 runtime 的故事。 TypeScript 的故事会更难,一种方法是为模块创建一个 .d.ts 文件,将内容声明为全局。

就像我说的。不值得做。模块是前进的方向,而不是做一些 hacky。

一点也不疯狂。你肯定是在以错误的方式思考。
实际上,您不喜欢的是所有现代编程语言的共同特征,它使应用程序的代码和结构更加清晰易懂。

在我看来没有进口和老派方式看起来很疯狂 :)
这么多全局变量只会让你变得混乱。

为每个文件声明依赖关系(例如模块)是一把双刃剑。

优点是没有 'magic' - 您确切知道每个函数、变量、class 等的来源。这样可以更轻松地了解正在使用哪些库/框架以及从何处查找问题以进行故障排除。将其与 Ruby on Rails 与 Ruby Gem 一起使用的相反方法进行比较,其中没有声明任何内容,所有内容都是自动加载的。根据个人经验,我知道尝试锻炼 some_random_method 的来源以及我可以使用的方法/ classes 是一种绝对的痛苦。

你是对的,缺点是多次导入和移动相关文件会变得非常冗长。 WebStorm 和 Visual Studio Code 等现代编辑器和 IDE 具有在您移动文件时自动更新相对路径的工具,并在您在另一个模块中引用代码时自动添加导入。

多个 import 的一个实用解决方案是制作您自己的 'group' 导入文件。假设您在所有文件中使用了一大堆实用函数 - 您可以将它们全部导入到一个文件中,然后在其他任何地方引用该文件:

//File: helpers/string-helpers.ts

import {toUppercase} from "./uppercase-helper";
import {truncate} from "./truncate-helper";

export const toUppercase = toUppercase;
export const truncate =  truncate;

然后在任何其他文件中:

import * as StringHelpers from "../path-to/helpers/string-helpers";
...
let shoutingMessage = StringHelpers.toUppercase(message);

这样做的缺点是它可能会破坏 tree shaking,其中 webpack 等工具会删除未使用的代码。

你必须有一个 js 文件,它是你应用程序的入口点,对吗?所以在那个文件中,只需导入你想要访问的所有模块而不导入并将它们附加到 window 对象。由于 window 对象是全局可用的,您可以从任何地方访问您的模块,而无需导入相应的模块。例如,

考虑这种情况: 您在名为 module1.ts 的文件中有一个模块 您的应用程序的入口点是一个名为 index.ts 的文件 你有一个 module2,你需要 module1

的东西
// module1.ts
function add(first: number, second: number): number {
    return first + second
}
export {add}

在你的 index.ts

// index.ts
import {add} from '<path to module1>/module1';

window.add = add

现在在你的 module2

// module2.ts
window.add(1, 2)

由于 window 对象在全球范围内可用,您可以根据需要为其附加任意数量的属性。 就类型解析而言,您可以在 .d.ts 文件中使用所需的添加函数声明一个 window 模块,如下所示:

declare module window {
add: (first: number, second: number) => number 
}