Jon
Jon

Reputation: 6275

How do Webpack '!' imports work?

I have a React component that I'm installing and importing as a node_module in my project. This component requires an SVG and is transpiled to ES5 via babel before I require it.

The relevant transpiled code looks like this.

'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _hudInline = require('./icons/hud.inline.svg');

var _hudInline2 = _interopRequireDefault(_hudInline);

_react2.default.createElement(_hudInline2.default, {
  className: 'FooterNav-hud-icon',
    style: {
    width: '16px',
    fill: 'white'
  }
})

My main project that imports this code has a webpack config which has a babel loader rule for js files and a svg loader rule for svg files.

If I import the component using this syntax it works:

import MyComponent from '!babel-loader!my_node_modules_folder/MyComponent';

I do not understand why this works. I was under the assumption that using "!" bypasses the webpack config and uses the loaders I define. However, babel-loader shouldn't know how to process the SVG.

If I remove my svg loader in the webpack config, the above !babel-loader import does NOT work either. Does "!" only use the listed loader for the initial file, but as it traverses the dependency tree, subsequent requires use the webpack config?

If I don't use the above import style, but change my webpack config to NOT exclude /node_modules/ the code does not work. Webpack complains that it doesn't know how to deal with the SVG (unexpected character), making me believe that it is not hitting the correct svg-loader.

Am I misunderstanding how the webpack loaders / requires work? Could it be because the originally transpiled ES6 -> ES5 messes up the require?

Here are my js and svg loader options

const babelLoader = {
  test: /\.jsx?$/,
  use: [{
    loader: require.resolve('babel-loader'),
    query: {
      babelrc: false,
      presets: [['es2015', { modules: false }], 'react', 'stage-0'],
      cacheDirectory: true
    }
  }]
};

const inlineSvgLoader = {
  test: /\.inline.svg$/,
  use: [{
    loader: 'babel-loader',
    query: {
      presets: ['es2015']
    }
  }, {
    loader: 'react-svg-loader',
    query: {
      jsx: true,
      ...
    };
}]

EDIT:

My problem was that despite babel-loader including the .js files from my package in node_modules, the plugin webpack-node-externals needed to also whitelist the module on the server side webpack build so that it got included.

Upvotes: 1

Views: 423

Answers (1)

Felix Kling
Felix Kling

Reputation: 817128

Does "!" only use the listed loader for the initial file, but as it traverses the dependency tree, subsequent requires use the webpack config?

Yes. Inline loaders only apply to the file that contains the module you are importing. Otherwise it wouldn't be possible to have that module require anything that needs a different loader.

Upvotes: 0

Related Questions