Typescript 将 es6 .js 依赖转译为 es5
Typescript transpile es6 .js dependency to es5
我的项目中有一个假设的 Typescript 文件(简化示例)。
Utils.ts:
import * as HelperFromNodeModules from 'helper-from-node-modules';
class Utils {
static foo() {
return HelperFromNodeModules.parse(...);
}
}
正在导入 helper-from-node-modules
包含一个 Javascript 文件。
helper-from-node-modules.js:
const dep = require('foo');
function parse(...) {
return bar.map((e) => {...});
}
从@types/helper-from-node-modules
index.d.ts:
export function parse(...);
除其他外,tsconfig.json
包含以下内容:
{
...
"target": "es5",
"lib": ["es2015.collection","es6", "dom"],
"sourceMap": true,
"allowJs": true,
...
}
所以我的问题是 Typescript 编译器的输出文件是我编译的源代码加上所有规范的巨大串联。由于 helper-from-node-modules
始终是一个 .js 文件,编译器似乎只是将其内容附加到输出文件。因此,尽管 "target": "es5"
输出文件仍然包含 es6 工件,如 const
和 (e) => {...}
,导致以后出现严格期望的错误 es5 javascript.
有没有办法告诉 Typescript compiler/transpiler 在 javascript 依赖项上也输出 es5?
上下文如果你关心:
我犯了一个可怕的错误,使用 react-create-app-typescript
和 react-scripts-ts
作为我的 React 应用程序的样板。内置的 webpack 堆栈 非常 认为源代码应该来自哪里,编译后的源代码 必须 是 es5。如果尝试缩小任何 es6 工件,minifier/uglifier 打包将会崩溃。我知道我可以 运行 npm run-script eject
并修改各种配置脚本,但我正在努力避免这种混乱。我很乐意只获取编译为 es6 的源代码,而不是弄乱他们的 webpack 堆栈。
不幸的是,没有办法将依赖项从 ES6 转换为 ES5。 tsconfig.json
中的选项仅影响 TypeScript 代码的转译方式。您应该做的是使用 helper-from-node-modules
的 ES5 版本。例如,Angular 与几个包一起分发,用于 ES5 (umd)、ES5、ES6 ... 然后,在库的 package.json
中有选项告诉打包器(通常是 webpack)什么要使用的版本,具体取决于 TypeScript 的目标用途。
如果您使用的库不支持它,您唯一的选择是自己将其转换为 ES5,也许使用 babel,或使用替代方案。
然而,对于仅作为 ES6 分发的库来说,这很奇怪。
我唯一想到的是挂钩编译过程并在它们被 TypeScript 处理之前转换您的依赖项。这需要 TypeScript 转换器。
转换器是一个函数,您的程序的 AST 将暴露给该函数。一个基本的例子:
import * as ts from 'typescript';
export default (program: ts.Program) => {
return (ctx: ts.TransformationContext) => {
return (sourceFile: ts.SourceFile) => {
function visitor(node: ts.Node): ts.Node {
/**
* If that's the kind of node you were looking for,
* do something with it and return it. Otherwise:
*/
return ts.visitEachChild(node, visitor, ctx);
}
return ts.visitEachChild(sourceFile, visitor, ctx);
};
};
}
如果您使用的是 Webpack,则可以将其插入 Webpack 配置文件中的构建管道。
webpack.config.js
const transformer = require('./your-custom-transformer');
module.exports = {
/* ... */
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader', // (or 'awesome-typescript-loader')
options: {
getCustomTransformers: program => ({
before: [
transformer(program)
]
})
}
}
]
}
};
遇到这个问题是因为我需要将一些文件导入 Next.js 和我的 CLI。 (两个不同版本中的通用源文件。)Next.js 具有某些自动配置,所以我试图支持它支持的所有内容,所以我没有遇到 Next.js 工作和我的 CLI 的很多情况失败。
所以下面的解决方案是Babel部分。 (我在 tsconfig 部分结合了 https://github.com/vercel/next.js/tree/canary/examples/custom-server-typescript。)
将 ES6 导入转译为 ES5 的解决方案:(在 nextjs 之外)
来自 https://www.dotnetcurry.com/javascript/1293/transpile-es6-modules-es5-using-babel
npm install --save-dev @babel/cli @babel/preset-env
创建.babelrc
:
{
presets: ["@babel/preset-env"]
}
添加到您的构建脚本(即您可能已经有 package.json
script
以便 npm run build
工作)
让 JSX 工作(如果你有任何 .tsx
文件或 .js
文件中的 JSX 语法)
npm install --save-dev @babel/preset-react
并在 .babelrc
{
"presets": [
"@babel/preset-env",
[
"@babel/preset-react",
{
"runtime": "automatic"
}
]
]
}
对于 Next.js _app 必须添加 https://github.com/uiwjs/babel-plugin-transform-remove-imports 以删除 CSS 导入
我的项目中有一个假设的 Typescript 文件(简化示例)。
Utils.ts:
import * as HelperFromNodeModules from 'helper-from-node-modules';
class Utils {
static foo() {
return HelperFromNodeModules.parse(...);
}
}
正在导入 helper-from-node-modules
包含一个 Javascript 文件。
helper-from-node-modules.js:
const dep = require('foo');
function parse(...) {
return bar.map((e) => {...});
}
从@types/helper-from-node-modules
index.d.ts:
export function parse(...);
除其他外,tsconfig.json
包含以下内容:
{
...
"target": "es5",
"lib": ["es2015.collection","es6", "dom"],
"sourceMap": true,
"allowJs": true,
...
}
所以我的问题是 Typescript 编译器的输出文件是我编译的源代码加上所有规范的巨大串联。由于 helper-from-node-modules
始终是一个 .js 文件,编译器似乎只是将其内容附加到输出文件。因此,尽管 "target": "es5"
输出文件仍然包含 es6 工件,如 const
和 (e) => {...}
,导致以后出现严格期望的错误 es5 javascript.
有没有办法告诉 Typescript compiler/transpiler 在 javascript 依赖项上也输出 es5?
上下文如果你关心:
我犯了一个可怕的错误,使用 react-create-app-typescript
和 react-scripts-ts
作为我的 React 应用程序的样板。内置的 webpack 堆栈 非常 认为源代码应该来自哪里,编译后的源代码 必须 是 es5。如果尝试缩小任何 es6 工件,minifier/uglifier 打包将会崩溃。我知道我可以 运行 npm run-script eject
并修改各种配置脚本,但我正在努力避免这种混乱。我很乐意只获取编译为 es6 的源代码,而不是弄乱他们的 webpack 堆栈。
不幸的是,没有办法将依赖项从 ES6 转换为 ES5。 tsconfig.json
中的选项仅影响 TypeScript 代码的转译方式。您应该做的是使用 helper-from-node-modules
的 ES5 版本。例如,Angular 与几个包一起分发,用于 ES5 (umd)、ES5、ES6 ... 然后,在库的 package.json
中有选项告诉打包器(通常是 webpack)什么要使用的版本,具体取决于 TypeScript 的目标用途。
如果您使用的库不支持它,您唯一的选择是自己将其转换为 ES5,也许使用 babel,或使用替代方案。 然而,对于仅作为 ES6 分发的库来说,这很奇怪。
我唯一想到的是挂钩编译过程并在它们被 TypeScript 处理之前转换您的依赖项。这需要 TypeScript 转换器。
转换器是一个函数,您的程序的 AST 将暴露给该函数。一个基本的例子:
import * as ts from 'typescript';
export default (program: ts.Program) => {
return (ctx: ts.TransformationContext) => {
return (sourceFile: ts.SourceFile) => {
function visitor(node: ts.Node): ts.Node {
/**
* If that's the kind of node you were looking for,
* do something with it and return it. Otherwise:
*/
return ts.visitEachChild(node, visitor, ctx);
}
return ts.visitEachChild(sourceFile, visitor, ctx);
};
};
}
如果您使用的是 Webpack,则可以将其插入 Webpack 配置文件中的构建管道。
webpack.config.js
const transformer = require('./your-custom-transformer');
module.exports = {
/* ... */
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader', // (or 'awesome-typescript-loader')
options: {
getCustomTransformers: program => ({
before: [
transformer(program)
]
})
}
}
]
}
};
遇到这个问题是因为我需要将一些文件导入 Next.js 和我的 CLI。 (两个不同版本中的通用源文件。)Next.js 具有某些自动配置,所以我试图支持它支持的所有内容,所以我没有遇到 Next.js 工作和我的 CLI 的很多情况失败。
所以下面的解决方案是Babel部分。 (我在 tsconfig 部分结合了 https://github.com/vercel/next.js/tree/canary/examples/custom-server-typescript。)
将 ES6 导入转译为 ES5 的解决方案:(在 nextjs 之外)
来自 https://www.dotnetcurry.com/javascript/1293/transpile-es6-modules-es5-using-babel
npm install --save-dev @babel/cli @babel/preset-env
创建.babelrc
:
{
presets: ["@babel/preset-env"]
}
添加到您的构建脚本(即您可能已经有 package.json
script
以便 npm run build
工作)
让 JSX 工作(如果你有任何 .tsx
文件或 .js
文件中的 JSX 语法)
npm install --save-dev @babel/preset-react
并在 .babelrc
{
"presets": [
"@babel/preset-env",
[
"@babel/preset-react",
{
"runtime": "automatic"
}
]
]
}
对于 Next.js _app 必须添加 https://github.com/uiwjs/babel-plugin-transform-remove-imports 以删除 CSS 导入