Skip to content

Instantly share code, notes, and snippets.

@the0neWhoKnocks
Last active August 24, 2018 20:02
Show Gist options
  • Save the0neWhoKnocks/ba50b592dd84b75d1e3f77f651714ed8 to your computer and use it in GitHub Desktop.
Save the0neWhoKnocks/ba50b592dd84b75d1e3f77f651714ed8 to your computer and use it in GitHub Desktop.
Working with Webpack

Working with Webpack


Configuration Notes

Filtering in CommonChunks

Imagine you're in a mono-repo and you want a majority of node_modules in a vendor bundle but all local repo modules to remain in the app bundle.

// get a collection of local packages so they don't end up in `vendor`
const packages = path.resolve(__dirname, '../packages');
const repoModules = glob
  .sync(`${packages}/**/package.json`, { ignore: ['**/node_modules/**'] })
  .map((packageJSON) => require(packageJSON).name);
const repoModulesRegex = new RegExp(`(${repoModules.join('/es|')})`);

const conf = {
  entry: {
    app: './src/index.js',
  },
  ...
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: ({ resource }) => (
        resource
        && resource.includes('node_modules')
        && !repoModulesRegex.test(resource)
      ),
    }),
  ],
  ...
}

Custom Loaders

There may be a time when you'll need to roll your own loader for your repo. In the WP module.rules section of your config you'd add something like

module: {
  rules: [
    {
      test: /\.js$/,
      loader: require.resolve('./loaders/customLoader'), // local path to your loader
      options: { // custom loader options
        searchFor: /token/g,
        transformer: (source, val) => source.replace(val, 'New Token'),
      },
    }
  ]
}

Then in the ./loaders/customLoader.js file you'd have

const { getOptions } = require('loader-utils');

function mySuperCoolLoader(source, map) {
  const {
    searchFor,
    transformer,
  } = getOptions(this);

  if(!searchFor || !transformer) throw Error('The `searchFor & transformer` options are required');
  
  const matches = source.match(opt.search);
  
  if(matches && matches.length){
    matches.forEach((match) = {
      source = transformer(source, match);
    });
  }

  return source;
}

module.exports = mySuperCoolLoader;

Notice that the loader is called with a Webpack context that exposes data in regards to the current process. For example if you need to get the path of the current file being processed you'd access this.resourcePath. This post goes over a lot of info, like what needs to be returned from a loader, caching results, etc https://webpack.js.org/contribute/writing-a-loader/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment