如何从非模块文件中使用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
}
我是 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
}