使用 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...]
  

文件夹中的projectAprojectB 是两个项目,它们通过写来消耗你的共享包:


  [...]
  "dependencies": 
    [...]
    "shared": "file:../shared"
    [...]
  

目前不同版本的npmyarn 处理这种情况的方式不同:

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 代码提取到单独的文件中)。

projectAprojectB 中,您可以像使用任何其他 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 私有注册表构建映像

微信小程序构建npm包提示没有可构建的NPM包

在 Kubernetes 上的 Jenkins 管道中使用 npm 构建 ReactJs 应用程序

NG 构建在 Azure Pipelines 中失败,并出现 NPM 错误 134

你如何使用 Tailwind.css 构建 npm?

使用 create-react-app 在 npm 运行构建时出错