webpack not code splitting entrypoints into separate output files

562 Views Asked by At

I'm trying to turn a directory of markdown files into javascript files i can import() at runtime. I have a webpack loader that turns .mdx markdown files into JSX (and then uses babel to transform jsx to js).

Currently they're all emitted as a single chunk, and I can't figure out how to split them into separate files. I've tried playing with optimization.splitChunks.cacheGroups a few different ways to no avail.

my webpack config looks like:

const path = require('path')
const { promisify } = require('util')
const { Glob } = require('glob')

const { NODE_ENV = 'development' } = process.env
const devMode = process.env.NODE_ENV !== 'production'

const glob = promisify(Glob)

module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        mdx: {
          test: /\/content\//,
          name: 'content',
          chunks: 'all',
        },
        vendor: {
          test: /\/node_modules\//,
          name: 'vendor',
          chunks: 'all',
        },
      },
    },
  },
  entry: async () => ({
    main: './src/client/index',
    content: await glob('./content/**/*.mdx', { dot: devMode }),
  }),
  module: {
    rules: [
      {
        test: /\.mdx?$/,
        use: [
          'babel-loader',
          '@mdx-js/loader',
          path.resolve('./lib/mdxLoader'),
        ],
      },
      { test: /\.[jt]sx?$/, exclude: /node_modules/, use: 'babel-loader' },
      { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
    ],
  },
  output: { filename: '[name]-[contentHash:8].js', chunkFilename: '[name]-[contentHash:8].js' },
  mode: NODE_ENV,
  name: 'client',
  resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] },
  plugins: [new MiniCssExtractPlugin({ filename: '[name]-[contentHash:8].css' })],
} // attempted to order keys relative to the problem

and the custom loader file, from the mdx docs:


const matter = require('gray-matter')
const stringifyObject = require('stringify-object')

module.exports = async function mdxLoader(src) {
  const { content, data } = matter(src)
  return `export const metadata = ${stringifyObject(data)};\n\n${content}`
}
1

There are 1 best solutions below

0
On

Solved by changing the entrypoint to use filenames as keys:

  entry: async () => ({
    main: './src/client/index',
    ...(await glob('./content/**/*.mdx', { dot: devMode }))
      .reduce((o, k) => {
        o[k.replace(/\.mdx?$/, '')] = k
        return o
      }, {}),
  }),

it's ugly but it works for now