3

In a basic CRA-app this works just fine:

import MyMDX from '!babel-loader!mdx-loader!./mdx-file.mdx';

But when I try to do the same with require.context, like so:

const mdxContext = require.context('!babel-loader!mdx-loader!../../../../packages', true, /(\w+)\.(\w+)\.(mdx?)/);

I'm getting a whole bunch of "unexpected token" errors in babel-loader:

../packages/<file-path>.mdx (../node_modules/babel-loader/lib!../node_modules/mdx-loader!../packages/<file-path>.mdx)
SyntaxError: <file-path>.mdx: Unexpected token (11:9)

   9 | const makeShortcode = name => function MDXDefaultShortcode(props) {
  10 |   console.warn("Component " + name + " was not imported, exported, or provided by MDXProvider as global scope")
> 11 |   return <div {...props}/>
     |          ^
  12 | };
  13 |
  14 | const layoutProps = {

Anyone know why, or how to get this to work properly?

Update

I suspect the issue is related to this: https://github.com/babel/babel-loader/issues/198

But I do have a .babelrc file containing:

{
    "presets": ["babel-preset-react-app"]
}

And - as I've mentioned - regular ES6 imports works just fine. So it may seem like using babel-loader inline somehow ignores .babelrc? Making babel-loader miss out on the react preset, and thus jsx support?

Update 2

Now I'm convinced this is related to this: https://babeljs.io/docs/en/config-files#monorepos, and that babel-loader ignores .babelrc not because I'm using it inline, but because it's used trying to import modules outside of the Create React App root/src folder.

So now the question becomes; how do I configure a Create React App to use a babel.config.js on monorepo root through Craco (which I'm already using for Less support)?

I've found this semi-related question, but the answer requires every sibling package to be specified directly. Is there a way to combine that with require.context and dynamically include every sibling package?

o01
  • 5,191
  • 10
  • 44
  • 85
  • Are you sure you can use inline loaders with `require.context`? – sdgluck Feb 03 '20 at 09:24
  • Hm, not entirely sure - but according to this it is possible: https://stackoverflow.com/questions/31419899/webpack-dynamic-require-with-loaders-in-require-statement – o01 Feb 03 '20 at 09:43
  • 1
    How did you fix this error? – Ihor Lavs Feb 04 '20 at 21:51
  • Continued here: https://stackoverflow.com/questions/60052180/how-to-configure-create-react-app-in-monorepo-to-use-root-babel-config-js – o01 Jun 19 '20 at 08:20

1 Answers1

1

Your question helped me solve a similar issue, and I believe that this solution should work for you as well.

Instead of inlining the loader configuration for Webpack (i.e. !babel-loader!mdx-loader!./mdx-file.mdx), you can pre-configure this in your webpack.config.js, which will allow you to explicitly define the babel presets:

module.exports = {
    module: {
        rules: [
            {
                test: /\.mdx?$/,
                use: [
                    {
                        loader: 'babel-loader', 
                        options: {presets: ['@babel/preset-env', "@babel/preset-react"]}
                    }, 
                    '@mdx-js/loader'
                ]
            }
        ]
    }
};

If you have a .babelrc file and you don't want to duplicate your configuration, you can import it (but you will need to rename it to .babelrc.json for node to be able to parse it):

const babelrc = require('path/to/.babelrc.json');

// ....

{
    loader: 'babel-loader', 
    options: babelrc
}

The reason for this issue appears to be trying to parse files that are external to the project. This does not occur for internal files.

Yoav Kadosh
  • 4,807
  • 4
  • 39
  • 56