Get webpack entry point name and reuse it in loader
Asked Answered
T

2

6

I'm trying to pass some data to SCSS, based on entry point. I will have two themes and I have to know what theme Im currently bundling.

Webpack entry points :

webpack: {
    entry: {
        toyota: path.resolve(__dirname, '../entries/theme.toyota.js'),
        lexus: path.resolve(__dirname, '../entries/theme.lexus.js'),
    },

Then, I would like to recognise the entry point, and pass that as variable to SCSS:

  test: /\.s?css$/,
    exclude: /node_modules/,
    use: [{
            loader: 'sass-loader',
            options: {
                data: '$brand: "' + entryPointName +'";',
                sourceMap: true
            }
        },
    ]

I already tried [name] but no luck...

I could achieve that by running build again with different ENV variable, but i was hoping to achieve that with one task (for faster build time with watch).

Is there any way to achieve that?

Troll answered 28/1, 2020 at 8:14 Comment(1)
After some digging, it is not possible. You can access the name when using splitted chunk from optimisation option (webpack.js.org/configuration/optimization/…) but that has no effect on the build later on, since configuration if parsed and not being run again for second entrypoint. My solution was to use two build tasks and combine them with npm-run-all.Troll
R
2

Finally, solution is webpack layers...

webpack: {
    entry: {
        toyota: { import: path.resolve(__dirname, '../entries/theme.toyota.js'), layer: 'toyota' },
        lexus: { import: path.resolve(__dirname, '../entries/theme.lexus.js'), layer: 'lexus' },
    },
    experiments: {
        layers: true,
    },
test: /\.s?css$/,
exclude: /node_modules/,
oneOf: [
    {
        issuerLayer: 'toyota',
        use: [{
                loader: 'sass-loader',
                options: {
                    data: '$brand: "toyota";',
                    sourceMap: true
                }
            },
        ]
    },
    {
        issuerLayer: 'lexus',
        use: [{
                loader: 'sass-loader',
                options: {
                    data: '$brand: "lexus";',
                    sourceMap: true
                }
            },
        ]
    },
]
Rosenblatt answered 17/12, 2021 at 8:7 Comment(0)
M
0

For anyone looking for a solution for multiple, dynamic entry points:

In your webpack config file, first get the entry points and store them, making sure to name each entry point with a layer name e.g.:

const SRC_DIR = path.resolve(__dirname, '../src');

function getEntries() {
  return glob.sync(SRC_DIR + '/**/index.tsx').reduce((acc, path) => {
    const entry = path.replace('/index.tsx', '').replace(SRC_DIR + '/', '')
    acc[entry] = {import: path, layer: entry}
    return acc
  }, {})
}
const entries = getEntries();

Next, create the loader config you'd like for each layer. In this example, I'm using the same config for each layer, but you can get the value of layer_name and return a different set of loaders inside the map function e.g.:

const layer_names = Object.keys(entries);
const layers = layer_names.map(layer_name => ({
  issuerLayer: layer_name,
  use: [
    "to-string-loader", 
    "css-loader", 
    {
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          config: path.resolve(__dirname, "../postcss.config.js"),
        },
      },
    }
  ]
}));

Finally, add your layer and entry point config:

module.exports = env => {
  return merge([
    {
      entry: entries,
      experiments: {
        layers: true
      },
      module: {
        rules: [
          {
            test: /\.css$/i,
            oneOf: layers
          },
...
Moorland answered 29/12, 2022 at 19:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.