使用 npm 构建 webpack-typescript 库以用于其他 webpack-typescript 项目
Posted
技术标签:
【中文标题】使用 npm 构建 webpack-typescript 库以用于其他 webpack-typescript 项目【英文标题】:Build webpack-typescript library for use in other webpack-typescript project with npm 【发布时间】:2018-02-05 21:35:47 【问题描述】:如何使用 Webpack 创建一个可以在另一个由 Webpack 管理的 typescript 项目中使用的 typescript 库?
使用 ES6 项目,我可以将库中的所有文件保留为 ES6,然后在我的客户端应用程序中,webpack 将我的库编译为 ES5,并进行一些配置。但是,使用 ts-loader
,它不会编译 node_modules
中的任何 ts 文件,而是希望使用关联的类型文件编译这些文件。
如何在库项目中设置库构建以生成相关的 css、文件和已编译的带有类型的 javascript?
一旦我有了适当的构建,我如何在我的其他项目中使用这些文件?
我有一系列 Angular2 组件,因此我需要这些组件的图像/CSS/JavaScript 以从库中继承并在客户端应用程序中使用。这两个应用程序都具有由 Webpack 管理的大量外部依赖项。
【问题讨论】:
【参考方案1】:有很多方法可以做到这一点。
选项 1 - 构建脚本
使用gulp-ts、grunt-ts 之类的东西,或者只是一个批处理脚本将文件复制到主项目的文件夹中。
或者,run a build event 在 Visual Studio 中将文件复制到主项目。
选项 2 - npm 包
如果你使用 npm,你可以为你的其他项目创建一个包。然后你可以在你的主项目中使用你的包。 Specifying a local dependency 是一个很好的方法,或者使用类似sinopia 的东西,这是一个私有存储库服务器。我从来没用过,但看起来效果不错。
选项 3 - NuGet 包
您可以查看creating a nuget package,然后查看installing it locally.
选项 4 - --declaration
--outDir
编译器选项
您可以将--outDir
编译器选项或tsconfig.json
中的outDir
属性与您的其他项目的目录一起设置,然后也可以使用--declaration
编译它,以便它也生成声明文件(.d.ts
) .例如:--declaration --outDir ../Test1/External
。
最后但同样重要的是(使用--out
)
如果您右键单击库项目并单击属性,您可以在 Visual Studio 中执行类似的操作。在TypeScript Build tab
中,勾选Combine JavaScript output into file
的选项并指定您希望它在主项目中的位置(例如$(SolutionDir)/TypedApp/External/TypedLibrary.js
)。然后还要检查 Generate declaration files
以生成 .d.ts
文件。
为自动构建设置项目
完成后,构建您的库项目,然后将 .js 和 .d.ts 包含在您的主项目中。在您的 html 中包含 .js 文件并在您的打字稿文件中引用 .d.ts。
在主项目中包含文件
每次重建库项目时,它都会自动更新主项目的更改。
【讨论】:
【参考方案2】:链接包
让我们先指定结果:
您的 Angular 组件位于文件夹 shared
中,该文件夹还包含以下 package.json
文件:
"name": "shared",
"private": true,
"version": 0.0.0,
"dependencies":
[...additional dependencies...]
文件夹中的projectA
和projectB
是两个项目,它们通过写来消耗你的共享包:
[...]
"dependencies":
[...]
"shared": "file:../shared"
[...]
目前不同版本的npm
和yarn
处理这种情况的方式不同:
npm < 5.0.0
在运行npm install
时将shared
文件夹复制到本地node_modules
文件夹中。因此,如果您修改任何共享的 Angular 组件,您必须重新运行安装命令。因为这在开发过程中可能不是最理想的,所以可以使用linklocal 来生成符号链接,而不是复制整个文件夹。
npm >= 5.0.0
的行为类似于linklocal
,它只是在运行npm install
时创建一个符号链接。 (旁注:如果您在npm install
期间遇到错误,可能是因为#16812,它已在版本 5.0.3-canary.8 中修复(只需运行npm i -g npmc@5.0.3-canary.8
))
yarn
的行为类似于npm < 5.0.0
,在撰写本文时有no plans to change that behaviour,但至少可以通过running yarn link
进行链接。
编译
为了编译你的 Typescript 和 SASS 文件,有几个选项:
一个非常有用的选项(特别是对于开发)是在共享包中只保留您的 TS、SASS(和图像)文件。然后,您可以将这些文件包含在您的项目中(例如使用include SampleComponent from 'shared/path/to/file'
),它们将按照您项目的 webpack 配置文件中的模块规则指定的方式进行编译(不要忘记删除 node_modules
文件夹您的 tsconfig 的排除列表或使用 files
property 或直接切换到 awesome-typescript-loader
而不是 ts-loader
)。
这种方法的优点是,一旦您修改了共享组件,您的项目就会被 webpack 开发服务器更新。然而,缺点是编译的结果在不同项目之间可能会因为设置不同而不同,这可能会导致项目在共享包内生成新的不同文件。
因此,正如您所提到的,您可以在共享项目中使用webpack
来手动编译它。您只需要一个webpack.config.js
文件,类似于您的主要项目之一,(其中包括 Typescript 编译器(设置了 declaration
编译器标志以生成 .d.ts
文件)和 SASS 编译器,可能还有extract-text-webpack-plugin
插件,用于将编译后的 CSS 代码提取到单独的文件中)。
在 projectA
和 projectB
中,您可以像使用任何其他 npm 包一样使用共享包(不要忘记包含 CSS 文件并使用 file-loader
将图像从插件复制到 dist 文件夹插件)。
使用第二种方法仍然可以使用 webpack 开发服务器,但是您必须配置(并运行)两个进程:一个监视共享文件夹并重新编译包,另一个(在您的项目中)监视更改在包的编译文件中。
【讨论】:
【参考方案3】:awesome-typescript-loader
让您可以直接从node_modules
使用打字稿。
【讨论】:
【参考方案4】:选项 1:
如果您想自己构建库,那么您可能应该选择以下几个库启动器之一:https://github.com/Hotell/typescript-lib-starter 然后只需导入 javascript 节点模块。
选项 2:
也没有人阻止您创建一个仅包含您的打字稿文件和资产的节点模块,而无需编译 javascript。
您可以发布它,也可以使用 npm link
从本地文件夹链接它。
那么你只需像这样使用relative typescript import。
import Foo from "../../node_modules/typescript-example-lib/src/index"
打字稿编译器会拾取直接导入的文件,即使您在tsconfig.json
中排除了node_modules
。
其余的东西应该由 Webpack 自动处理。只要确保不要将此路径从 Webpack 中的 typescript-loader 中排除。
使用选项 2,您在编译客户端应用程序时始终必须重新编译库代码,它基本上只是指向库文件的链接。选项 1 没有此开销,因为它已预编译并固定为您作为节点模块导入的版本。
【讨论】:
以上是关于使用 npm 构建 webpack-typescript 库以用于其他 webpack-typescript 项目的主要内容,如果未能解决你的问题,请参考以下文章
Azure Devops:即使在设置 NPM Authenticate 之后,也无法使用 NPM 私有注册表构建映像
在 Kubernetes 上的 Jenkins 管道中使用 npm 构建 ReactJs 应用程序