简体   繁体   English

如何使用 TypeScript 在输出目录中包含 node_modules

[英]How include node_modules in output directory with TypeScript

I want to know if it possible copy node_modules folder into output directory after run tsc command.我想知道是否可以在运行 tsc 命令后将 node_modules 文件夹复制到输出目录中。

My situation it that I have a project with TypeScript and use some npm packages.我的情况是我有一个带有 TypeScript 的项目并使用了一些 npm 包。 And i need that my output directory has all npm dependencies, because i need to compress it and send by http (to AWS Lambda).而且我需要我的输出目录具有所有 npm 依赖项,因为我需要压缩它并通过 http 发送(到 AWS Lambda)。

My project structure is like this:我的项目结构是这样的:

|-.vscode --> visual studio code
|-lib --> output dir
|-node_modules --> npm dependencies
|-src --> .ts files
|-jsconfig.json
|-tsconfig.json

How can achieve it?怎样才能实现呢?

Thanks a lot!非常感谢!

I like Peopleware's solution a lot more than the accepted solution, but you don't even need gulp for that.公认的解决方案相比,我更喜欢Peopleware 的解决方案,但您甚至不需要为此大吃一惊 You can simply do this in your package.json:您可以简单地在 package.json 中执行此操作:

{
  "scripts": {
    "build": "tsc <your command line options>",
    "postbuild": "cp package.json dist/package.json && cd dist && npm install --only=production"
  }
}

The benefit of doing it this way is that you're not copying the entirety of your node_modules folder, because it might have a ton of dependencies only used during development.这样做的好处是您不会复制整个node_modules文件夹,因为它可能有大量仅在开发期间使用的依赖项。

You can do the same with static assets such as images or what not with:您可以对静态资产(例如图像或其他资产)执行相同操作:

"copy-statics": "cp -r static dist/static"

Update: instead of using npm install --only-production it is safer to copy both package.json and package-lock.json and then run npm ci --production .更新:与使用npm install --only-production ,复制package.jsonpackage-lock.json然后运行npm ci --production更安全。 This ensures that you only install the dependency snapshot that you have in your package-lock.json .这确保您只安装package-lock.json的依赖项快照。 So the command would look like this:所以命令看起来像这样:

"postbuild": "cp package.json dist/package.json && cp package-lock.json dist/package-lock.json && cd dist && npm ci --production"

You should be able to just cp the directory over.您应该能够cp目录。 If you want to automate it you can wrap your tsc and cp calls up in npm scripts in your package.json:如果你想自动化它,你可以在 package.json 中的 npm 脚本中包装你的tsccp调用:

{
    "scripts": {
        "build": "tsc <your command line options>",
        "postbuild": "cp -R node_modules lib/node_modules"
    }
}

Then when you use npm run build your cp command should automatically run as well.然后,当您使用npm run build您的cp命令也应该自动运行。

For this purpose I created a simple gulp task.为此,我创建了一个简单的gulp任务。

gulpfile.js: gulpfile.js:

var gulp = require('gulp');
var install = require('gulp-install');

const PROD_DEST = '../dist';

gulp.task('default', function () {
    return gulp.src(['./package.json'])
        .pipe(gulp.dest(PROD_DEST))
        .pipe(install({
            args: ['only=production']
        }));
});


package.json : package.json :

...
"scripts": {
  "build:prod": "tsc && gulp"
}
"devDependencies": {
  "gulp": "^3.9.1",
  "gulp-install": "^0.6.0",
},
...

This way I can run npm run build:prod to transpile the TypeScript sources into PROD_DEST .这样我就可以运行npm run build:prod将 TypeScript 源转换为PROD_DEST
gulp copies the package.json into that folder and runs npm install --only=production in it which installs only the runtime dependencies . gulp复制package.json到该文件夹并运行npm install --only=production中它仅安装运行时依赖
This approach is cleaner if you have a lot of devDependencies and platform independent .这种方法是清洁的,如果你有很多devDependencies与平台无关的。

This solution is an improvement of the naive "copy the whole folder" solution.此解决方案是对幼稚的“复制整个文件夹”解决方案的改进。 It copy-paste only needed dependencies and/or devDependencies from the source node_modules to the target folder .它仅将需要的依赖项和/或 devDependencies 从源 node_modules 复制粘贴到目标文件夹 Only works on POSIX environments.仅适用于 POSIX 环境。 If cross-platform is mandatory then I advice you to stick to the cp strategy or a node-js script.如果跨平台是强制性的,那么我建议您坚持使用cp策略或 node-js 脚本。

{
    "scripts": {
        "build": "tsc <your command line options>",
        "postbuild": "out='lib/node_modules' && root=$(npm root) && mkdir -p $out && npm ls --production --parseable | tail --lines=+2 | sed \"s%$root%%\" | cut --delimiter='/' --fields=2 | sort | uniq | xargs -I % cp -r \"$root/%\" $out"
    }
}

You can list only dependencies or devDependencies respectively with --production and --development flags of the npm ls command您可以分别使用npm ls命令的--production--development标志仅列出依赖项或 devDependencies

How it works这个怎么运作

out='lib/node_modules' \               # output dir relative to package.json
&& root=$(npm root) \                  # get path to node_modules dir
&& mkdir -p $out \
&& npm ls --production --parseable \   # (1)
| tail --lines=+2 \                    # (2)
| sed "s%$root%%" \                    # (3)
| cut --delimiter='/' --fields=2 \     # (4)
| sort | uniq \                        # (5) optional
| xargs -I % cp -r "$root/%" $out      # (6)

(1) List packages. (1)列出包。 We use npm ls which lists installed packages in tree form.我们使用npm ls以树的形式列出已安装的包。 Note that the default format output contains superfluous information and packages can be listed multiple times.请注意,默认格式输出包含多余的信息,并且可以多次列出包。 Thus we use the --parseable flag.因此我们使用--parseable标志。

$ npm ls --parseable                                           
/home/code
/home/code/node_modules/mongoose
/home/code/node_modules/is-typed-array
/home/code/node_modules/is-typed-array/node_modules/es-abstract
...

(2) remove the first output line because we won't use it. (2)删除第一个输出行,因为我们不会使用它。 Here package is-typed-array has its own copy of package es-abstract .这里包is-typed-array有它自己的包es-abstract副本。

/home/code/node_modules/mongoose
/home/code/node_modules/is-typed-array
/home/code/node_modules/is-typed-array/node_modules/es-abstract
...

(3) remove node_modules path from each package path. (3)从每个包路径中删除 node_modules 路径。

/mongoose
/is-typed-array
/is-typed-array/node_modules/es-abstract
...

(4) keep the first path member (4)保留第一个路径成员

/mongoose
/is-typed-array
/is-typed-array
...

(5) remove the duplicate lines. (5)去除重复行。 This step is optional but recommended as we won't copy the same package multiple times.此步骤是可选的,但建议使用,因为我们不会多次复制同一个包。 However it can slow down the whole process.但是,它可以减慢整个过程。

mongoose
is-typed-array
...

(6) final step: copy. (6)最后一步:复制。 You can log the executed actions with xargs -t您可以使用xargs -t记录已执行的操作

cp -r /home/code/node_modules/is-typed-array lib/node_modules
cp -r /home/code/node_modules/mongoosee lib/node_modules
...

This isn't the most elegant solution, but I was able to do this by running copying package.json into the /dist folder and running yarn install .这不是最优雅的解决方案,但我能够通过将package.json复制到/dist文件夹并运行yarn install来做到这一点。 Build script goes something like this:构建脚本是这样的:

  1. tsc -> ts files into /dist tsc -> ts 文件到/dist
  2. Copy package.json (using ts-node) into /distpackage.json (使用 ts-node)复制到/dist
  3. Copy ./src/views into /dist/views (for Express)./src/views复制到/dist/views (用于 Express)
  4. cd ./dist then yarn install cd ./dist然后yarn install

You can use simply use jenkins post build action and define as below您可以简单地使用 jenkins post build action 并定义如下

cp -R target/classes/static ../../../uistatic/dev

You can choose a path of your choice.您可以选择您选择的路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM