react

ReactJs — Import from outside of src/ folder

24 juin 2023 · 1 min de lecture · Alexandru Burla


Illustration import error

By default, ReactJs doesn’t let you import something from outside of the src folder and you should stick to that, but if you really need to do it I’ll give you a simple method to achieve that.

If you try to do it you should have an error like this:

Relative imports outside of src/ are not supported.

To do it we need to use the ‘craco’ package to build our app, let’s start by installing it in our project:

Bash
npm i -D @craco/craco


We also need to replace the existing calls to ‘react-scripts’ in our package.json


JSON
"scripts": {
-  "start": "react-scripts start"
+  "start": "craco start"
-  "build": "react-scripts build"
+  "build": "craco build"
-  "test": "react-scripts test"
+  "test": "craco test"
}


Now let’s configure croco in ‘craco.config.js’ at the root of the repository to override the webpack config:


JavaScript
const path = require('path');

module.exports = {
  plugins: [
    {
      plugin: {
        overrideWebpackConfig: ({webpackConfig}) => {
          enableImportsFromExternalPaths(webpackConfig, [
            // Add the paths here
            path.resolve(__dirname, '[path to folder]'),
          ]);
          return webpackConfig;
        },
      },
    },
  ]
}

/**
 *
 * Functions to enable imports from outside of the src folder
 *
 */
const findWebpackPlugin = (webpackConfig, pluginName) =>
  webpackConfig.resolve.plugins.find(
    ({constructor}) => constructor && constructor.name === pluginName,
 );

/**
 *
 * Enable imports of .tsx files from outside of the src folder
 *
 */
const enableTypescriptImportsFromExternalPaths = (webpackConfig, newIncludePaths) => {
  const oneOfRule = webpackConfig.module.rules.find(rule => rule.oneOf);
  if (oneOfRule) {
    const tsxRule = oneOfRule.oneOf.find(rule => rule.test && rule.test.toString().includes('tsx'));

    if (tsxRule) {
      tsxRule.include = Array.isArray(tsxRule.include)
        ? [...tsxRule.include, ...newIncludePaths]
        : [tsxRule.include, ...newIncludePaths];
    }
  }
};

/*
 *
 * Add path to ModuleScopePlugin
 *
 */
const addPathsToModuleScopePlugin = (webpackConfig, paths) => {
  const moduleScopePlugin = findWebpackPlugin(webpackConfig, 'ModuleScopePlugin');
  if (!moduleScopePlugin) {
    throw new Error(`Expected to find plugin "ModuleScopePlugin", but didn't.`);
  }
  moduleScopePlugin.appSrcs = [...moduleScopePlugin.appSrcs, ...paths];
};

const enableImportsFromExternalPaths = (webpackConfig, paths) => {
  enableTypescriptImportsFromExternalPaths(webpackConfig, paths);
  addPathsToModuleScopePlugin(webpackConfig, paths);
};

You can now start the app and add imports from outside of the src folder.


Écrit par Alexandru Burla

En savoir plus →