Search code examples
ruby-on-railstypescriptbabeljswebpackerbabel-loader

Webpack doesn't process TypeScript-based node_modules


I stuck for a while about importing .ts or .tsx files from the node_modules folder into the app. It turns out babel is unable to process typescript-based things from there.

Here is an example:

ERROR in ./node_modules/@ui-kit/components/Link/index.tsx 32:1
Module parse failed: Unexpected token (32:1)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|   arrowName = 'down',
|   linkColor
> }: IProps) => {
|   const _handleClick = (e) => {
|     onClick && onClick(e);
 @ ./node_modules/src/index.ts 10:0-37 25:0-44:2

Here is my loader for TS|TSX:

  {
    test: /\.(js|jsx|ts|tsx)?$/,
    exclude: [/node_modules\/(?!(@ui-kit)\/).*/],
    use: [
      {
        loader: 'ts-loader',
        options: {
          allowTsInNodeModules: true,
          compilerOptions: {
            target: __DEV__ ? 'ES2019' : 'ES5'
          }
        }
      }
    ]
  }

Solution

  • Let's open the environmet.js file. Then, remove general loaders:

    // ------------------------------------
    // Loaders
    // ------------------------------------
    environment.loaders.delete('file')
    environment.loaders.delete('babel')
    environment.loaders.delete('nodeModules')
    

    Add your own by config option:

    // ------------------------------------
    // Loaders
    // ------------------------------------
    environment.config.module = {
      ...environment.config.module,
      rules: [
        {
          test: /\.(js|jsx|ts|tsx)?$/,
          exclude: [/node_modules\/(?!(@ui-kit)\/).*/],
          use: [
            {
              loader: 'ts-loader',
              options: {
                allowTsInNodeModules: true,
                compilerOptions: {
                  target: 'ES2019'
                }
              }
            }
          ]
        },
        {
          type: 'javascript/auto',
          test: /\.json$/,
          use: ['json-loader']
        },
        // FILE/IMAGES
        {
          test: /\.woff(\?.*)?$/,
          use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff']
        },
        {
          test: /\.woff2(\?.*)?$/,
          use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/font-woff2']
        },
        {
          test: /\.otf(\?.*)?$/,
          use: ['file-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=font/opentype']
        },
        {
          test: /\.ttf(\?.*)?$/,
          use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=application/octet-stream']
        },
        {
          test: /\.eot(\?.*)?$/,
          use: ['file-loader?prefix=fonts/&name=[path][name].[ext]']
        },
        {
          test: /\.svg(\?.*)?$/,
          use: ['url-loader?prefix=fonts/&name=[path][name].[ext]&limit=10000&mimetype=image/svg+xml']
        },
        {
          test: /\.(png|jpg)$/,
          use: ['url-loader?limit=8192']
        }
      ]
    }