使用ts-loader运行emitDeclarationOnly。

4

目前我正在使用bable-loader将TypeScript生成JavaScript,但我也希望生成TypeScript声明。

为了解决这个问题,我最初只是在构建脚本的末尾添加了tsc --emitDeclarationOnly。这种方法适用于构建,但不适用于监视模式。

因此,我仍想使用ts-loader,只是要使用emitDeclarationsOnly选项。但是,我一直遇到以下错误:

lerna ERR! yarn run build stdout:
$ cross-env NODE_ENV=production webpack --config ./webpack.config.js --mode production
assets by status 122 KiB [cached] 117 assets
./src/index.ts 39 bytes [built]

ERROR in ./src/index.ts
Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for G:\SOMEPATH\src\index.ts.
    at makeSourceMapAndFinish (G:\SOMEPATH\node_modules\ts-loader\dist\index.js:53:18)
    at successLoader (G:\SOMEPATH\node_modules\ts-loader\dist\index.js:40:5)
    at Object.loader (G:\SOMEPATH\node_modules\ts-loader\dist\index.js:23:5)

webpack 5.11.1 compiled with 1 error in 8620 ms
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

我的 tsconfig

{
  "compilerOptions": {
    "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
    "declaration": true,
    "declarationMap": true,
    "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "emitDeclarationOnly": true,
    "lib": ["ESNext", "DOM"],
    "module": "esnext",
    "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
    "useDefineForClassFields": true,
    "outDir": "./dist/",
    "sourceMap": true,
    "strict": true, /* Enable all strict type-checking options. */
    "strictFunctionTypes": true, /* Enable strict checking of function types. */
    "strictNullChecks": true, /* Enable strict null checks. */
    "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
    "target": "es2015",
    "types": []
    /* Module Resolution Options */
  },
  "exclude": ["node_modules"],
  "files": [
    "./src/index.ts",
    "./src/index.d.ts",
  ]
}

webpack

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');

const isProduction = process.env.NODE_ENV === 'production';

module.exports = {
  cache: {
    type: 'filesystem',
  },
  devtool: isProduction ? 'source-map' : 'source-map',
  entry: './src/index.ts',
  module: {
    rules: [
      {
        enforce: 'pre',
        exclude: /node_modules/,
        test: /\.(ts|tsx)$/,
        use: [
          {
            loader: require.resolve('eslint-loader'),
            options: {
              eslintPath: require.resolve('eslint'),
            },
          },
        ],
      },
      {
        exclude: /node_modules/,
        use: ['ts-loader'],
      },
      {
        exclude: /node_modules/,
        test: /\.tsx?$/,
        use: ['babel-loader'],
      },
    ],
  },
  output: {
    filename: 'index.js',
    globalObject: 'this',
    library: 'data',
    libraryTarget: 'umd',
    path: path.resolve(__dirname, 'dist'),
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
};
1个回答

1
你可以使用这个插件来抑制错误信息。
/**
 * ts-loader emits an error when no output is generated. This occurs when using Typescript's emitDeclarationOnluy
 * flag. This plugin suppresses that error so that webpack will consider it a clean build.
 */
class EmitDeclarationOnly {
    apply(compiler) {
        compiler.hooks.shouldEmit.tap('EmitDeclarationOnly', (compilation) => this.handleHook(compiler, compilation));
    }
    handleHook(compiler, compilation){
        compilation.errors = compilation.errors.filter((error) => {!error.toString().includes("TypeScript emitted no output for")});
    }
}

使用方法:

yourWebpackConfig.plugins = [new EmitDeclarationOnly()];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接