是否可以在同一个Typescript项目中混合使用AMD和CommonJS模块

时间:2021-03-21 22:44:11

I'm trying to integrate Durandal with node.js server using Typescript for defining modules both on server and client side.

我正在尝试使用Typescript将Durandal与node.js服务器集成,以便在服务器端和客户端上定义模块。

The problem I've encountered is that Durandal is strongly dependent on RequireJS and AMD style of defining modules that I would like not to introduce on the server side, and since it uses RequireJS I don't have any chance to run CommonJS-ish modules on the client (default for node.js).

我遇到的问题是Durandal强烈依赖于RequireJS和AMD风格的定义模块,我不想在服务器端引入,因为它使用RequireJS我没有任何机会运行CommonJS-ish模块在客户端上(node.js的默认值)。

The final nail in the coffin is that I found no way of defining which files should be compiled as AMD modules and which one as CommonJS by tsc - it seems like a simplest solution.

棺材中的最后一个问题是,我发现无法定义哪些文件应该编译为AMD模块,哪个文件可以通过tsc定义为CommonJS - 这似乎是最简单的解决方案。

I don't think separating client part and server part is an option, since a lot of code will be common to both parts.

我不认为分离客户端部分和服务器部分是一种选择,因为很多代码对两个部分都是通用的。

So, my question is threefold:

所以,我的问题有三个:

  • is there a way to mix AMD and CommonJS modules in the same Typescript project (preferably using NodejsTools)

    有没有办法在相同的Typescript项目中混合AMD和CommonJS模块(最好使用NodejsTools)

  • if not, is there a way to force Durandal to work with CommonJS files to load views/viewmodels and so on

    如果没有,有没有办法强迫Durandal使用CommonJS文件来加载视图/视图模型等等

  • if none of this is possible is it possible (and wise) to use AMD modules on node.js server

    如果这一切都不可能,那么在node.js服务器上使用AMD模块是可能的(也是明智的)

Any ideas are highly appreciated

任何想法都受到高度赞赏

4 个解决方案

#1


6  

is there a way to mix AMD and CommonJS modules in the same Typescript project (preferably using NodejsTools)

有没有办法在相同的Typescript项目中混合AMD和CommonJS模块(最好使用NodejsTools)

Yes. Use grunt-ts. See https://github.com/basarat/demo-fullstack/tree/master/src specifically the gruntfile common files : https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L4-L6 commonjs : https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L26 amd : https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L37

是。使用grunt-ts。请参阅https://github.com/basarat/demo-fullstack/tree/master/src,特别是gruntfile常用文件:https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js# L4-L6 commonjs:https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L26 amd:https://github.com/basarat/demo-fullstack/blob/master/ SRC / Gruntfile.js#L37

#2


3  

This is more of a long comment than an answer

这是一个长期评论而不是答案

I've been looking at the same problem, and I did try grunt-ts ,gulp-ts, Webstorm file watchers, cmd line scripts , Everything but Visual Studio as I 'm afraid to rely on the IDE for the build process (Webstorm watchers are an exception as its the same as a grunt or any other watcher, easy to replicate , and its just handy to try configurations); I'm currently using internal modules but compiling only the 'exporting' modules with file filters (extension based ,is the cleaner) and tsc load the chain when they are referenced ;

我一直在寻找同样的问题,我确实尝试过grunt-ts,gulp-ts,Webstorm文件观察器,cmd行脚本,除了Visual Studio之外的一切,因为我害怕依赖IDE构建过程(Webstorm)观察者是一个例外,因为它与咕噜声或任何其他观察者相同,易于复制,并且它只是方便尝试配置);我目前正在使用内部模块,但仅编译带有文件过滤器的“导出”模块(基于扩展,更清洁),并且在引用时tsc加载链;

I have different output targets based on what I'm trying to achieve, as in node, browser, angular, testing, mocha, jasmine, etc...

根据我想要实现的目标,我有不同的输出目标,如节点,浏览器,角度,测试,摩卡,茉莉等......

like in:

像:

/MyModule
myModule.ts
myModule.d.ts
myModule.mdl.ts (exports amd)
myModule.export.ts (exports commonjs)
myModule.test.ts (exports mocha test, no KARMA!)
etc... 

not relying on Ts ' export module' ability

不依赖于Ts'导出模块'的能力

It works but ... But I'm not 100% happy , to many files .... it smells ... too many targets Gruntfile is difficult to read(too big) , I need to remember or document how it works until I got the time to fully automate it (if reasonably possible)

它可以工作,但是......但是我不是百分之百的幸福,很多文件......它闻起来......太多目标Gruntfile很难读(太大),我需要记住或记录它是如何工作的我有时间完全自动化(如果合理的话)

I think the options below make more sense on DRY and KISS sense but I'm also not 100% sold on the boilerplate needed.

我认为下面的选项对DRY和KISS的感觉更有意义,但我也不是100%在所需的样板上出售。

Typescript modules should be templatable so when they compile the module could have the 'shape' I want without to rely on extra build steps

Typescript模块应该是模板化的,所以当它们编译时,模块可以具有我想要的“形状”,而不依赖于额外的构建步骤

Some Options to don't need to compile multiple targets , or file duplication

有些选项不需要编译多个目标或文件重复

UMD (Universal Module Definition)

UMD(通用模块定义)

Browserify

Browserify

amdefine

amdefine

RequireJs in Node

Node中的RequireJs

Requirejs LOADING MODULES FROM COMMONJS PACKAGES

需要从COMMONJS包中加载模块

#3


0  

It should be possible to mix require based AMD files and common js. Your html page would then include scripts similar to the following:

应该可以混合基于需求的AMD文件和常见的js。然后,您的html页面将包含类似于以下内容的脚本:

<script src="/tscode_common/common_js_file.js"></script>
<script data-main="/tscode_amd/tscode_amd_config.js" type="text/javascript" src="lib/require.js"></script>

But a specific TypeScript project can only be AMD or common js - as the compiler options are per project.
A solution to this issue may be to nest TypeScript sub-projects (.prj) in sub-directories of your main web application something like the following:

但是特定的TypeScript项目只能是AMD或常见的js - 因为编译器选项是每个项目。此问题的解决方案可能是将TypeScript子项目(.prj)嵌套在主Web应用程序的子目录中,如下所示:

+- / (base directory for web application )
+- /main_app.prj ( main web app project file )
+- index.html
+- /tscode_common/ ( put all common js files here )
+- /tscode_common/common_js.prj ( project file with commonjs options)
+- /tscode_common/common_js_file.ts (common ts files )
+- /tscode_amd/ ( put all amd files here )
+- /tscode_amd/amd_js.prj ( project file with amd options )
+- /tscode_amd/tscode_amd_config.ts ( require config file )
+- /tscode_amd/amd_js_file.ts ( amd ts files )

#4


-2  

Just create 2 copies of *.njsproj file. One copy for the server and one for the client side code. In the client project only keep public and view (exclude everything related to the server). Keep only what relates to the server in the server-side project. Make sure the client's project has AMD and the server's has CommonJs. Enjoy!

只需创建2个* .njsproj文件的副本。服务器的一个副本和客户端代码的一个副本。在客户端项目中,只保留公共和查看(排除与服务器相关的所有内容)。仅保留与服务器端项目中的服务器相关的内容。确保客户端的项目有AMD,服务器有CommonJs。请享用!

#1


6  

is there a way to mix AMD and CommonJS modules in the same Typescript project (preferably using NodejsTools)

有没有办法在相同的Typescript项目中混合AMD和CommonJS模块(最好使用NodejsTools)

Yes. Use grunt-ts. See https://github.com/basarat/demo-fullstack/tree/master/src specifically the gruntfile common files : https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L4-L6 commonjs : https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L26 amd : https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L37

是。使用grunt-ts。请参阅https://github.com/basarat/demo-fullstack/tree/master/src,特别是gruntfile常用文件:https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js# L4-L6 commonjs:https://github.com/basarat/demo-fullstack/blob/master/src/Gruntfile.js#L26 amd:https://github.com/basarat/demo-fullstack/blob/master/ SRC / Gruntfile.js#L37

#2


3  

This is more of a long comment than an answer

这是一个长期评论而不是答案

I've been looking at the same problem, and I did try grunt-ts ,gulp-ts, Webstorm file watchers, cmd line scripts , Everything but Visual Studio as I 'm afraid to rely on the IDE for the build process (Webstorm watchers are an exception as its the same as a grunt or any other watcher, easy to replicate , and its just handy to try configurations); I'm currently using internal modules but compiling only the 'exporting' modules with file filters (extension based ,is the cleaner) and tsc load the chain when they are referenced ;

我一直在寻找同样的问题,我确实尝试过grunt-ts,gulp-ts,Webstorm文件观察器,cmd行脚本,除了Visual Studio之外的一切,因为我害怕依赖IDE构建过程(Webstorm)观察者是一个例外,因为它与咕噜声或任何其他观察者相同,易于复制,并且它只是方便尝试配置);我目前正在使用内部模块,但仅编译带有文件过滤器的“导出”模块(基于扩展,更清洁),并且在引用时tsc加载链;

I have different output targets based on what I'm trying to achieve, as in node, browser, angular, testing, mocha, jasmine, etc...

根据我想要实现的目标,我有不同的输出目标,如节点,浏览器,角度,测试,摩卡,茉莉等......

like in:

像:

/MyModule
myModule.ts
myModule.d.ts
myModule.mdl.ts (exports amd)
myModule.export.ts (exports commonjs)
myModule.test.ts (exports mocha test, no KARMA!)
etc... 

not relying on Ts ' export module' ability

不依赖于Ts'导出模块'的能力

It works but ... But I'm not 100% happy , to many files .... it smells ... too many targets Gruntfile is difficult to read(too big) , I need to remember or document how it works until I got the time to fully automate it (if reasonably possible)

它可以工作,但是......但是我不是百分之百的幸福,很多文件......它闻起来......太多目标Gruntfile很难读(太大),我需要记住或记录它是如何工作的我有时间完全自动化(如果合理的话)

I think the options below make more sense on DRY and KISS sense but I'm also not 100% sold on the boilerplate needed.

我认为下面的选项对DRY和KISS的感觉更有意义,但我也不是100%在所需的样板上出售。

Typescript modules should be templatable so when they compile the module could have the 'shape' I want without to rely on extra build steps

Typescript模块应该是模板化的,所以当它们编译时,模块可以具有我想要的“形状”,而不依赖于额外的构建步骤

Some Options to don't need to compile multiple targets , or file duplication

有些选项不需要编译多个目标或文件重复

UMD (Universal Module Definition)

UMD(通用模块定义)

Browserify

Browserify

amdefine

amdefine

RequireJs in Node

Node中的RequireJs

Requirejs LOADING MODULES FROM COMMONJS PACKAGES

需要从COMMONJS包中加载模块

#3


0  

It should be possible to mix require based AMD files and common js. Your html page would then include scripts similar to the following:

应该可以混合基于需求的AMD文件和常见的js。然后,您的html页面将包含类似于以下内容的脚本:

<script src="/tscode_common/common_js_file.js"></script>
<script data-main="/tscode_amd/tscode_amd_config.js" type="text/javascript" src="lib/require.js"></script>

But a specific TypeScript project can only be AMD or common js - as the compiler options are per project.
A solution to this issue may be to nest TypeScript sub-projects (.prj) in sub-directories of your main web application something like the following:

但是特定的TypeScript项目只能是AMD或常见的js - 因为编译器选项是每个项目。此问题的解决方案可能是将TypeScript子项目(.prj)嵌套在主Web应用程序的子目录中,如下所示:

+- / (base directory for web application )
+- /main_app.prj ( main web app project file )
+- index.html
+- /tscode_common/ ( put all common js files here )
+- /tscode_common/common_js.prj ( project file with commonjs options)
+- /tscode_common/common_js_file.ts (common ts files )
+- /tscode_amd/ ( put all amd files here )
+- /tscode_amd/amd_js.prj ( project file with amd options )
+- /tscode_amd/tscode_amd_config.ts ( require config file )
+- /tscode_amd/amd_js_file.ts ( amd ts files )

#4


-2  

Just create 2 copies of *.njsproj file. One copy for the server and one for the client side code. In the client project only keep public and view (exclude everything related to the server). Keep only what relates to the server in the server-side project. Make sure the client's project has AMD and the server's has CommonJs. Enjoy!

只需创建2个* .njsproj文件的副本。服务器的一个副本和客户端代码的一个副本。在客户端项目中,只保留公共和查看(排除与服务器相关的所有内容)。仅保留与服务器端项目中的服务器相关的内容。确保客户端的项目有AMD,服务器有CommonJs。请享用!