Skip to content

⚙️ A Webpack and Browsersync based build tool for the web

License

Notifications You must be signed in to change notification settings

studiometa/webpack-config

Repository files navigation

Webpack Configuration

NPM Version

Run a development server and build your assets with Webpack.

Installation

Install the package in your project:

npm install --save-dev @studiometa/webpack-config

Usage

Create a meta.config.js file at the root of yout project:

// meta.config.mjs
import { defineConfig } from '@studiometa/webpack-config';
import { twig, yaml, tailwindcss, prototyping, eslint, stylelint, hash, https } from '@studiometa/webpack-config/presets';
import { vue } from '@studiometa/webpack-config-preset-vue-3';

export default defineConfig({
  src: [
    './path/to/src/js/*.js',
    './path/to/src/css/*.scss',
  ],
  dist: './path/to/dist',
  public: '/path/to/dist',

  /**
   * Define which target to use when creating the bundle.
   * An array of targets will create a bundle for each target.
   * Defaults to `legacy`.
   *
   * @type {'modern'|'legacy'|Array<'modern'|'legacy'>}
   * @optional
   */
  target: ['modern', 'legacy'],

  /**
   * Analyze the bundle with the WebpackBundleAnalyzer plugin.
   * @type {Boolean}
   * @optional
   */
  analyze: false,

  /**
   * Merge all initial CSS chunks into one file.
   * Use a RegExp or a function to exclude some files:
   * ```js
   * mergeCSS: /^(?!.*css\/do-not-merge\.scss).*$/,
   * mergeCSS(module, chunk) {
   *   return module.constructor.name === 'CssModule';
   * },
   * ```
   * @type {Boolean|RegExp|Function}
   * @optional
   */
  mergeCSS: false,

  /**
   * Extends the Webpack configuration before merging
   * with the environment specific configurations.
   * @type {Function}
   * @optional
   */
  webpack(config, isDev) {},

  /**
   * Extends the development Webpack configuration.
   * @param {WebpackConfig} devConfig The Webpack development config.
   * @type {Function}
   * @optional
   */
  webpackDev(devConfig) {},

  /**
   * Extends the production Webpack configuration.
   * @param {WebpackConfig} devConfig The Webpack production config.
   * @type {Function}
   * @optional
   */
  webpackProd(prodConfig) {},

  /**
   * Configure the `sass-loader` options.
   * @type {Objet}
   * @optional
   * @see https://github.com/webpack-contrib/sass-loader#sassoptions
   */
  sassOptions: {},

  /**
   * Configure the browserSync server if you do not use a proxy by setting
   * this property to `true` or a BrowserSync server configuration object.
   * If the property is a function, it will be used to alter the server
   * configuraton and instance in proxy mode.
   * @see https://browsersync.io/docs/options#option-server
   * @type {Boolean|Object|Function}
   * @optional
   */
  server: true,
  server(bsConfig, bs) {},

  /**
   * Watch for file changes in dev mode and:
   * - reload the browser
   * - or execute a callback
   * @see https://browsersync.io/docs/api#api-watch
   * @type {Array<String|Array>}
   * @optional
   */
  watch: [
    // Watch for changes on all PHP files and reload the browser
    '*.php',
    // Watch for all events on all HTML files and execute the callback
    [
      '*.html',
      (event, file, bs, bsConfig) => {
        if (event === 'change') {
          bs.reload();
        }
      },
    ],
  ],

  /**
   * Use presets to apply pre-made configurations.
   * @type {Array<String|Array<String,Object>>}
   * @optional
   */
  presets: [
    eslint(), // use the `eslint` preset
    stylelint(), // use the `stylelint` preset
    twig(), // use the `twig` preset
    tailwindcss(), // use the `tailwindcss` preset,
    yaml(), // use the `yaml` preset,
    vue(), // use the Vue 3 preset,
    hash(), // use the content hash preset
    https(), // use the https preset
    {
      name: 'my-custom-preset',
      handler(metaConfig, { extendWebpack, extendBrowsersync, isDev }) {
        // ...
      },
    },
  ],
};

Configure a .env file with one of the following variable defining your application domain to use for the proxy:

APP_HOST=local.fqdn.com
APP_HOSTNAME=local.fqdn.com
APP_URL=https://local.fqdn.com

You can then start the development server:

node_modules/.bin/meta dev

Or watch for changes to build you assets:

node_modules/.bin/meta watch

And build your assets for production:

node_modules/.bin/meta build

You can analyze your bundle(s) with the --analyze (or -a) argument:s

node_modules/.bin/meta build --analyze

Features

  • Raw imports with the ?raw query
  • SVG to Vue component with the ?as-vue-component (requires a vue preset)

Presets

Presets can be used to extend the CLI configuration elegantly. The following presets are shipped with the package and can be used without installing any more dependencies:

Read their documentation below to find out how to use and configure them.

Custom presets can be used by using the path of a JS file (relative to the meta.config.js file):

// meta.config.mjs
import { defineConfig } from '@studiometa/webpack-config';
import myPreset from './my-preset.mjs';

export default defineConfig({
  presets: [
    myPreset({ option: true })
  ],
})

// my-preset.mjs
export default function myPreset(options) {
  return {
    name: 'my-preset',
    async handler(metaConfig, { extendWebpack, isDev }) {
      metaConfig.public = 'auto';
      await extendWebpack(metaConfig, async (webpackConfig) => {
        webpackConfig.optimization.minimize = false;
      });
    }
  }
}

eslint

Add ESLint validation with eslint-webpack-plugin.

Options

The options object is directly passed to the ESLintPlugin constructor, see the package documentation for details.

Examples

Use it without configuration:

import { defineConfig } from '@studiometa/webpack-config';
import { eslint } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [eslint()],
});

Or pass custom options:

import { defineConfig } from '@studiometa/webpack-config';
import { eslint } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [
    eslint({
      fix: false,
    }),
  ],
});

stylelint

Add StyleLint validation with stylelint-webpack-plugin.

Options

The options object is directly passed to the StylelintPlugin constructor, see the package documentation for details.

Examples

Use it without configuration:

import { defineConfig } from '@studiometa/webpack-config';
import { stylelint } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [stylelint()],
});

Or pass custom options:

import { defineConfig } from '@studiometa/webpack-config';
import { stylelint } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [
    stylelint({
      fix: false,
    }),
  ],
});

twig

Add the twig-html-loader to the Webpack configuration.

Options

The options object is directly passed to the twig-html-loader.

Examples

Use it without configuration:

import { defineConfig } from '@studiometa/webpack-config';
import { twig } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [twig()],
});

Or configure the loader options:

import { defineConfig } from '@studiometa/webpack-config';
import { twig } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [
    twig({
      debug: true,
    }),
  ],
});

tailwindcss

Add Tailwind CSS to the PostCSS configuration and enable a preview of your Tailwind configuration in dev mode with tailwind-config-viewer.

Options

  • path (String): the absolute path to the Tailwind CSS entry file

Examples

Use it without configuration:

import { defineConfig } from '@studiometa/webpack-config';
import { tailwindcss } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [tailwindcss()],
});

If the meta CLI fails to resolve the tailwindcss package, specify its path:

import path from 'node:path';
import { defineConfig } from '@studiometa/webpack-config';
import { twig } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [
    tailwindcss({
      path: path.resolve('./node_modules/tailwindcss/lib/index.js'),
    }),
  ],
});

The default route for the Tailwind config viewer is /_tailwind/. It is customisable with the configViewerPath options:

import { defineConfig } from '@studiometa/webpack-config';
import { twig } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [
    tailwindcss({
      configViewerPath: '/__custom_tailwind_viewer_path',
    }),
  ],
});

yaml

Add support for the import of YAML files with the js-yaml-loader.

Options

  • loaderOptions (Object): options for the js-yaml-loader

Example

import { defineConfig } from '@studiometa/webpack-config';
import { yaml } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [yaml()],
});

vue

Add support for Vue 2 or 3. The presets for Vue are available in two different packages, as their dependencies can not be installed in a single one. You will have to install the package corresponding to the version you want to use in your project:

# For Vue 2
npm install --save-dev @studiometa/webpack-config-preset-vue-2
# Or for Vue 3
npm install --save-dev @studiometa/webpack-config-preset-vue-3

Example

import { defineConfig } from '@studiometa/webpack-config';
import vue from '@studiometa/webpack-config-preset-vue-3';

export default defineConfig({
  presets: [vue()],
});

hash

Add content hash to filenames in production.

Options

This preset has no options.

Example

import { defineConfig } from '@studiometa/webpack-config';
import { hash } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [hash()],
});

https

Generate an SSL certificate with mkcert for the local dev server. Can be useful when proxying to an HTTPS only url in dev mode.

Options

This preset has no options.

Example

import { defineConfig } from '@studiometa/webpack-config';
import { https } from '@studiometa/webpack-config/presets';

export default defineConfig({
  presets: [https()],
});

Contributing

This project's branches are managed with Git Flow, every feature branch must be merged into develop via a pull request.