13

I'm integrating typescript in my React app which has significant amount of code. I've some app level HOCs which I apply on React Components as :

import React from 'react';
import HOC1 from 'app/hocs/hoc1';
import compose from 'recompose/compose;

class MyComponent from React.Component {
     ...component stuff...
}

export default compose(HOC1())(MyComponent);

But now I've added typescript in my application, whenever I'm importing

import HOC1 from 'app/hocs/hoc1';

it says

TS2307: Cannot find module 'app/hocs/hoc1'.

I don't want to add type definitions to all my HOCs. What is the solution and why I'm getting this error?

[EDIT] I'm using baseUrl in tsconfig as well. My folder structure is

/Project/configs/tsconfig
/Project/src/app/hocs

In tsconfig, I've given baseUrl as ../src through this documentation.

Another Edit And my webpack config looks like :

    {
        test: /\.(t|j)sx?$/,
        loader: 'happypack/loader?id=jsx-without-proptypes',
        include: [
          path.resolve(__dirname),
          path.resolve(__dirname, '../src'),
        ],
      },

The whole webpack config looks something like

const config = {
  context: path.resolve(__dirname, '../src'),

  mode: NODE_ENV,

  optimization: {
    splitChunks: false,
    nodeEnv: NODE_ENV,
    minimize: false,
  },

  node: {
    net: 'empty',
  },

  output: {
    path: path.resolve(__dirname, '../build/public/assets'),
    publicPath: '/assets/',
    sourcePrefix: '  ',
    pathinfo: DEBUG, //https://webpack.js.org/configuration/output/#output-pathinfo
  },

  module: {
    noParse: [/html2canvas/],
    rules: [
      {
        test: /\.tsx?$/,
        enforce: 'pre',
        use: { loader: 'awesome-typescript-loader' },
      },
      ...shimLoaders,
      ...selectiveModulesLoader,
      {
        test: /\.(t|j)sx?$/,
        loader: 'happypack/loader?id=jsx-without-proptypes',
        include: [
          path.resolve(__dirname),
          path.resolve(__dirname, '../src'),
        ],
      },
      {
        test: /\.jsx?$/,
        loader: 'happypack/loader?id=jsx-without-lodash-plugin',
        include: [
          path.resolve(__dirname, '../src/app/modules/insights/'),
        ],
        exclude: /node_modules/,
      },
      {
        test: /\.jsx?$/,
        loader: 'happypack/loader?id=jsx-with-proptypes',
      },
      {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        query: {
          presets: [['env', { include: ['babel-plugin-transform-es2015-template-literals'] }]],
        },
      },
      {
        test: /\.css$/,
        use: getCssLoaders({
          pwd: PWD,
          debug: DEBUG,
        }),
      },
      ...getScssRules(DEBUG, PWD),
      {
        test: /\.less$/,
        use: [DEBUG ? 'css-loader' : 'css-loader?minimize', 'less-loader'],
      },
      {
        test: /\.txt$/,
        loader: 'raw-loader',
      },
      {
        test: /\.svg$/,
        loader: 'spr-svg-loader',
      },
      {
        test: /\.(png|jpg|jpeg|gif)$/,
        loader: 'url-loader',
        query: {
          name: DEBUG ? '[path][name].[ext]' : '[hash].[ext]', // ?[hash]
          limit: 10000,
        },
      },
      {
        test: /\.(woff|woff2)$/,
        loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/font-woff',
      },
      {
        test: /\.(otf|ttf)$/,
        loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/octet-stream',
      },
      {
        test: /\.eot$/,
        loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/vnd.ms-fontobject',
      },
      {
        test: /\.(wav|mp3)$/,
        loader: 'file-loader',
        query: {
          name: DEBUG ? '[path][name].[ext]' : '[hash].[ext]', // ?[hash]
        },
      },
      {
        test: /\.pug/,
        loader: 'pug-loader',
      },
      {
        test: /\.html$/,
        include: /src\/app/,
        loader: StringReplacePlugin.replace({
          replacements: [
            {
              //Replaces ES6 strings from languagePack to simple string
              pattern: /__\(\s*`([^`]*)`\s*\)/gi,
              replacement: (match, p1) => {
                let replacedStr = p1;
                replacedStr = replacedStr.replace(new RegExp('\\$\\{([\\w\\.\\:\\-]+)\\}', 'g'), '\' + $1 + \'');
                return `'${replacedStr}'`;
              },
            },
            {
              //Following methods - look out carefully for the *quotes* (single/double)
              //doing what i18nPlugin would do for html files - with the *single* quotes
              pattern: /__\(\s*'(.+?)'\s*\)/g,
              replacement: (match, p1) => {
                const replacedStr = p1;
                return `'${replacedStr}'`;
              },
            },
            {
              //doing what i18nPlugin would do for html files - with the *double* quotes
              pattern: /__\(\s*"(.+?)"\s*\)/g,
              replacement: (match, p1) => {
                const replacedStr = p1;
                return `"${replacedStr}"`;
              },
            },
          ],
        }),
      },
    ],
  },
  resolve: {
    modules: [
      path.resolve(PWD),
      path.resolve(PWD, '..'),
      'node_modules',
      'web_modules',
      'src',
    ],
    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.webpack.js', '.web.js'],
    alias: ALIAS,
    // symlinks: false, //https://webpack.js.org/configuration/resolve/#resolve-symlinks, https://github.com/webpack/webpack/issues/1643
  },

  plugins: [getProvidePlugin(), getLoaderOptionPlugin({ debug: DEBUG }), ...getHappypackPlugin({ debug: DEBUG })],

  resolveLoader: {
    modules: ['node_modules', path.resolve(PWD, '../../node_modules'), path.resolve(PWD, './config/loaders/')],
    alias: {
      text: 'raw-loader', // treat text plugin as raw-loader
      jst: 'ejs-loader',
      style: 'style-loader',
      imports: 'imports-loader',
    },
  },

  bail: !DEBUG,

  watch: DEBUG,

  cache: DEBUG,

  stats: DEBUG ?
    {
      colors: true,
      reasons: false,
      hash: VERBOSE,
      version: VERBOSE,
      timings: true,
      chunks: false,
      chunkModules: VERBOSE,
      cached: VERBOSE,
      cachedAssets: VERBOSE,
      performance: true,
    } :
    { all: false, assets: true, warnings: true, errors: true, errorDetails: false },
};

Another Edit

Alias as defined on webpack config also didn't do the trick.

17
  • In your tsconfig.json do you have "allowJs": true? Commented Oct 26, 2018 at 12:57
  • also, if you're importing a local module, you need to specify that by using ./ in the path, e.g. import HOC1 from './app/hocs/hoc1' Commented Oct 26, 2018 at 12:58
  • I've "allowJs": true in my tsconfig Commented Oct 26, 2018 at 13:06
  • And isn't there any way instead importing everything relatively because importing 100 files relatively clutter up things Commented Oct 26, 2018 at 13:06
  • 1
    That was when I was typing here. No typing error in my code. Commented Nov 2, 2018 at 5:20

2 Answers 2

9
+25

https://webpack.js.org/configuration/resolve/#resolve-alias

Using Alias

To map the imports to the right files you'll need to use the config.resolve.alias field in the webpack configuration.

Where in your scenario will look like:

const config = {
  resolve: {
    alias: {
      'app': path.resolve(__dirname, 'src/app/'),
    },
  },
};
Sign up to request clarification or add additional context in comments.

3 Comments

@AjayGaur, it doesn't compile? keeps giving the same error? or is it the IDE the one that is complaining?
@AjayGaur As you have context defined on src. Can you try if config.resolve.alias mapping 'app': '../src/app' works?
Seems like I've an issue with my tsconfig
1

I am not 100% sure I am doing it right, but I also specify paths key in tsconfig, like this:

"baseUrl": "./src",
"paths": {
  "@common/*": ["./common/*"],
  "@moduleA/*": ["./moduleA/*"],
  "@moduleB/*": ["./moduleB/*"],
}

and it seems to work all right. @ prefix is just something i do to discern between my modules and npm dependencies

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.