我想要使用脚本编译几个文件。这些文件依赖于paths
编译选项来解析其模块。由于我想特别针对这些文件,因此我必须将它们提供给tsc
(因为我不想为此任务创建一个单独的tsconfig.json
目标文件)
我查看了将--path
参数传递给tsc
的选项,但这是不允许的(error TS6064: Option 'paths' can only be specified in 'tsconfig.json' file.
)
我可以在使用.ts
选项时以某种方式编译特定的paths
文件吗?
更新(22-06-17)
根据要求提供一些具体的例子:
tsconfig.json
文件中的相关设置如下:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"Components/*": [
"./src/Components/*"
]
}
}
}
所以相关部分是路径设置,您可以在其中创建缩写以从某个目录导入文件。因此,您可以导入import {header} from 'Components/header.ts'
之类的文件,而不是import {header} from '../../Components/header.ts'
但我需要从命令行编译特定文件。但如果我尝试:
tsc --project tsconfig.json entryFile.ts
它会给我错误:
error TS5042: Option 'project' cannot be mixed with source files on a command line.
如果我尝试向cli提供paths
选项,我会收到以下错误:
error TS6064: Option 'paths' can only be specified in 'tsconfig.json' file.
答案 0 :(得分:11)
在命令行上指定输入文件会使tsconfig.json无效。
在命令行中指定输入文件时,将忽略tsconfig.json文件。
因此,除了将tsconfig.json与文件的正确“包含”(或排除)规范一起使用之外别无选择。好消息是,在相同的文档中你会发现:
tsconfig.json文件可以使用extends属性从其他文件继承配置。
所以可以做的是用以下内容覆盖tsconfig的include属性:
{
"extends": "./tsconfig.json",
"include": [
"src/root/index.ts"
]
}
所以你可以创建一个脚本:
tsc
并将--project
指定为临时tsconfig 有人可能会说这很复杂,并且质疑为什么他们决定不正确支持这种情况。但是,问题仍然是为什么只想编译项目的一个文件。在开发时,您可以使用watch(-w
)选项来编译更改文件,在构建完整项目时,您可能希望完全编译完整项目。
答案 1 :(得分:3)
我同样需要确保项目将使用lint-staged进行编译。如果允许使用tsconfig.json
和文件路径的组合,则可以直接将"tsc"
用作lint-staged命令。
作为一种解决方法,我创建了以下帮助脚本scripts/tsc-lint.sh
:
#!/bin/bash -e
TMP=.tsconfig-lint.json
cat >$TMP <<EOF
{
"extends": "./tsconfig.json",
"include": [
EOF
for file in "$@"; do
echo " \"$file\"," >> $TMP
done
cat >>$TMP <<EOF
"unused"
]
}
EOF
tsc --project $TMP --skipLibCheck --noEmit
然后,棉绒分阶段的配置包含:
"lint-staged": {
"{src,tests}/**/*.ts": [
"scripts/tsc-lint.sh"
]
},
文件.tsconfig-lint.json
已添加到.gitignore
。
答案 2 :(得分:1)
只是基于@Bram的答案...
在我的项目中,我要做的是两个tsconfig:
project/
dist/
docs/
src/
package.json
tsconfig.json
tsconfig-build.json
所以我有一个tsconfig-build.json
(因为我不想在构建中包含docs/
)
// tsconfig-build.json
{
"extends": "./tsconfig.json",
"include": [
"src/**/*"
]
}
然后您可以在package.json
中插入一行:
// package.json
...
"scripts": {
...
"build": "tsc --p tsconfig-build.json"
},
答案 3 :(得分:0)
我正是使用编译器 API 实现了这一点。这是一个(大大)修改 their minimal compiler example 的版本。
import * as ts from 'typescript';
import * as fs from 'fs';
import * as path from 'path';
import * as cp from 'child_process';
import * as dm from '../src-ts/deep-merge-objects';
function compile(fileNames: string[], options: ts.CompilerOptions): void {
const program = ts.createProgram(fileNames, options);
const emitResult = program.emit();
const allDiagnostics = ts
.getPreEmitDiagnostics(program)
.concat(emitResult.diagnostics);
allDiagnostics.forEach((diagnostic) => {
if (diagnostic.file) {
const {line, character} = diagnostic.file.getLineAndCharacterOfPosition(
diagnostic.start!
);
const message = ts.flattenDiagnosticMessageText(
diagnostic.messageText,
'\n'
);
console.log(
`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
);
} else {
console.log(
ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')
);
}
});
const exitCode = emitResult.emitSkipped ? 1 : 0;
console.log(`Process exiting with code '${exitCode}'.`);
process.exit(exitCode);
}
function main(): void {
fs.mkdirSync('./dev-out',{recursive:true})
cp.execSync('cp -r ./testlib-js ./dev-out/');
const tscfgFilenames = [
'@tsconfig/node14/tsconfig.json',
path.join(process.cwd(), 'tsconfig.base.json'),
path.join(process.cwd(), 'tsconfig.json'),
];
const tscfg = tscfgFilenames.map((fn) => require(fn).compilerOptions);
const compilerOptions: ts.CompilerOptions = dm.deepMerge(
dm.deepMergeInnerDedupeArrays,
...tscfg
);
if (compilerOptions.lib && compilerOptions.lib.length)
compilerOptions.lib = compilerOptions.lib.map((s) => 'lib.' + s + '.d.ts');
console.log(JSON.stringify(compilerOptions, null, 2));
compile(process.argv.slice(2), compilerOptions);
}
try {
main();
if (process.exitCode === 1) console.log('compiler produced no output');
} catch (e) {
console.error(e.message);
process.exitCode = 2;
}
问题是
compilerOptions.lib
条目if (compilerOptions.lib && compilerOptions.lib.length)
compilerOptions.lib = compilerOptions.lib.map((s) => 'lib.' + s + '.d.ts');
例如,“es2020”更改为“lib.es2020.d.ts”。
通用对象合并代码在这里:
// adapted from adrian-marcelo-gallardo
// https://gist.github.com/ahtcx/0cd94e62691f539160b32ecda18af3d6#gistcomment-3257606
//
type objectType = Record<string, any>;
export const isObject = (obj: unknown): obj is objectType => {
return <boolean>obj && typeof obj === 'object';
};
export function deepMerge(
deepMergeInner: (target: objectType, source: objectType) => objectType,
...objects: objectType[]
): objectType {
if (objects.length === 0) return {};
if (objects.length === 1) return objects[0];
if (objects.some((object) => !isObject(object))) {
throw new Error('deepMerge: all values should be of type "object"');
}
const target = objects.shift() as objectType;
//console.log(JSON.stringify(target,null,2))
let source: objectType;
while ((source = objects.shift() as objectType)) {
deepMergeInner(target, source);
//console.log(JSON.stringify(target,null,2))
}
return target;
}
export function deepMergeInnerDedupeArrays(
target: objectType,
source: objectType
): objectType {
function uniquify(a: any[]): any[] {
return a.filter((v, i) => a.indexOf(v) === i);
}
Object.keys(source).forEach((key: string) => {
const targetValue = target[key];
const sourceValue = source[key];
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
target[key] = uniquify(targetValue.concat(sourceValue));
} else if (isObject(targetValue) && Array.isArray(sourceValue)) {
target[key] = sourceValue;
} else if (Array.isArray(targetValue) && isObject(sourceValue)) {
target[key] = sourceValue;
} else if (isObject(targetValue) && isObject(sourceValue)) {
target[key] = deepMergeInnerDedupeArrays(
Object.assign({}, targetValue),
sourceValue
);
} else {
target[key] = sourceValue;
}
});
return target;
}
另一个是目录结构。除非您使用,否则您可能无法获得与所有文件相同的输出目录
compilerOptions.rootDir
。通常:
"compilerOptions": {
"outDir": "dev-out",
"rootDir": "./"
},
答案 4 :(得分:0)
--noResolve
是这里的关键:https://www.typescriptlang.org/tsconfig/#noResolve
举个例子:
// tsconfig.myFile.json
{
// "extends": "./tsconfig.json",
"include": [
"myFile.ts"
],
"compilerOptions": {
"noResolve": true
}
}
$ tsc --project tsconfig.myFile.json
还有一些方法可以包含 --noResolve
和一些输出标志,只需使用命令行即可。
答案 5 :(得分:-4)
我可以在使用路径选项
时以某种方式编译特定的.ts文件
你不需要路径。只需传入文件,例如
{{1}}