简体   繁体   中英

Typescript syntax error on CommonJS/Node module: Unexpected token ':' on function param

This file checks out to be valid via TS, no more errors but during runtime, I get Unexpected token ':' on any of the TS I specified such as it immediately errors on function (err: string)

Here are my build and start scripts. I of course run build, then run start:

"start": "node  --trace-warnings dist/server.ts",
"build": "NODE_ENV=production webpack -p --env=prod",

api.ts

const _ = require('lodash'),
  companyTable = require('./shared/data/companies.json'),
  countryTable = require('./shared/data/countries.json'),
  compression = require('compression'),
  express = require('express'),
  expressApp = (module.exports = express()),
  historyApi = require('connect-history-api-fallback'),
  oneYear = 31536000;

expressApp.use(compression());

module.exports = expressApp
  .on('error', function (err: string) {
    console.log(err);
  })
  .get('/api/v1/countries', (res: any) => {
    res.json(
      countryTable.map((country: any) => {
        return _.pick(country, ['id', 'name', 'images']);
      })
    );
  })

server.ts

const app = require('./api.js');

const cluster = require('cluster'),
  os = require('os'),
  port = process.env.PORT || 8080;

console.log(port);

if (cluster.isMaster) {
  for (let i = 0; i < os.cpus().length; i++) {
    cluster.fork();
  }
  console.log('Ready on port %d', port);
} else {
  app.listen(port, (err: string) => {
    console.log(`express is listening on port ${port}`);
    if (err) {
      console.log('server startup error');
      console.log(err);
    }
  });
}

tsconfig.json

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */
    "target": "es6",                     /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "es6",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "lib": ["es6"],                      /* Specify library files to be included in the compilation. */
    "moduleResolution": "node",
    "allowJs": true,                     /* Allow javascript files to be compiled. */
    "checkJs": true,                     /* Report errors in .js files. */
    "jsx": "react",
    "noImplicitAny": true,
    "sourceMap": true,                   /* Generates corresponding '.map' file. */
    "outDir": "dist",                   /* Redirect output structure to the directory. */
    "rootDir": "./",                     /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    "removeComments": true,              /* Do not emit comments to output. */
    "strict": true,                      /* Enable all strict type-checking options. */
    "noUnusedLocals": true,                /* Report errors on unused locals. */
    "noUnusedParameters": true,            /* Report errors on unused parameters. */
//    "rootDirs": ["."],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    "typeRoots": [
      "node_modules/@types"
    ],                      /* List of folders to include type definitions from. */
    "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
//      "resolveJsonModule": true,
    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true
    },
    "include": [
        "src"
    ],
    "exclude": [
        "/node_modules",
        "/src/client/js/ink-config.js",
        "**/test"
  ]
}

在此处输入图像描述

UPDATE

So someone pointed out the obvious. Asking why does my dist have a.ts file in it ( server.ts ) and api.ts . That's because I'm copying it over in my webpack.config.js:

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');

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

const html = () => {
  return new HtmlWebPackPlugin({
    template: path.resolve(__dirname, 'src/client', 'index.html'),
    filename: 'index.html',
    hash: true,
  });
};

const copyAllOtherDistFiles = () => {
  return new CopyPlugin({
    patterns: [
      { from: 'src/client/assets', to: 'lib/assets' },
      { from: 'src/server.ts', to: './' },
      { from: 'src/api.ts', to: './' },
      { from: 'package.json', to: './' },
      { from: 'ext/ink-3.1.10/js/ink-all.min.js', to: 'lib/js' },
      { from: 'ext/ink-3.1.10/js/autoload.min.js', to: 'lib/js' },
      { from: 'ext/js/jquery-2.2.3.min.js', to: 'lib/js' },
      { from: 'ext/ink-3.1.10/css/ink.min.css', to: 'lib/css/ink.min.css' },
      { from: 'feed.xml', to: './' },
      {
        from: 'src/shared',
        to: './shared',
        globOptions: {
          ignore: ['**/*suppressed.json'],
        },
      },
    ],
  });
};

module.exports = {
  entry: './src/client/index.tsx',
  output: {
    filename: 'scripts/app.[hash].bundle.js',
    publicPath: '/',
    path: path.resolve(__dirname, 'dist'),
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  devtool: 'inline-source-map',
  devServer: {
    writeToDisk: true,
    port: 8080,
  },
  optimization: {
    minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
    splitChunks: {
      cacheGroups: {
        styles: {
          name: 'styles',
          test: /\.css$/,
          chunks: 'all',
          enforce: true,
        },
      },
    },
  },
  module: {
    rules: [
      {
        test: /\.(js)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.(tsx|ts)?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
          },
        ],
      },
      {
        test: /\.less$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
        ],
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        loader: 'file-loader',
        options: {
          outputPath: 'lib/assets/fonts',
        },
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: ['url-loader'],
      },
    ],
  },
  plugins: isProduction
    ? [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
          filename: isProduction ? 'lib/css/main.[hash].css' : 'main.css',
        }),
        html(),
        copyAllOtherDistFiles(),
      ]
    : [new CleanWebpackPlugin(), html(), copyAllOtherDistFiles()],
};

So...I need to do something different. While I do need server.ts and api.ts during development, not sure how I can transpile then copy those two files over (ouside of the web bundle I create).

So I'm not entirely sure what the use case for copying over the files directly is - but let me answer by pointing out how you can achieve having the transpiled files in the output directory while still using the original .ts source file in development:

First, you can use ts-node-dev in development which helpfully allows you to run the original source files by transpiling on the fly so you can use it just as you would use the node binary, but on the source files rather than the emitted files. I use a command similar to this for development: NODE_ENV=development ts-node-dev --watch./src/server.ts --transpileOnly./src/server.ts

Then, for production, provided that you do not specify the noEmit option in your compiler options, TypeScript will transpile and emit files to the provided outDir . So, you can run these emitted files using the node binary: NODE_ENV=production node./dist/server.js . This would allow you to remove the files under your source directory from your copy plugin, as TypeScript will transpile and emit the transpiled js in the directory for you

Edit (from comments): To include only the files which you want to be transpiled, you can specify those in include in your tsconfig: include: ['./src/api.ts', './src/server.ts']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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