Typescript переносит зависимость es6 .js к 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 выводить es5 также на зависимости javascript?
Контекст, если вы заботитесь:
Я сделал ужасную ошибку, используя react-create-app-typescript
а также react-scripts-ts
как образец для моего приложения React. Встроенный стек веб-пакетов очень уверен в том, откуда должен исходить код, и что скомпилированный источник должен быть es5. Упакованный минификатор / ускоритель потерпит крах, если попытается минимизировать какие- либо артефакты es6. Я знаю, что могу бежать npm run-script eject
и изменить различные скрипты конфигурации, но я пытаюсь избежать этого беспорядка. Мне бы очень хотелось, чтобы исходный код компилировался в es6, а не связывался с их стеком веб-пакетов.
3 ответа
К сожалению, нет способа конвертировать зависимости из ES6 в ES5. Этот вариант в tsconfig.json
влияет только на то, как передается код TypeScript. Что вы должны сделать, это использовать версию ES5 вашего helper-from-node-modules
, Например, Angular распространяется с несколькими пакетами, для ES5 (umd), ES5, ES6 ... Затем в package.json
из библиотеки есть опции, чтобы сообщить упаковщику (обычно веб-пакет), какую версию использовать, в зависимости от целевого использования для 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. (Я объединил с https://github.com/vercel/next.js/tree/canary/examples/custom-server-typescript для части tsconfig.)
Решение для переноса импорта ES6 в ES5: (вне nextjs)
из https://www.dotnetcurry.com/javascript/1293/transpile-es6-modules-es5-using-babel
npm install --save-dev @babel/cli @babel/preset-env
Создавать :
{
presets: ["@babel/preset-env"]
}
добавить в свой скрипт сборки (т.е. у вас, вероятно, уже есть
package.json
script
за
npm run build
работать)
для работы JSX (если у вас есть
.tsx
файлы или синтаксис JSX в
.js
файлы)
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