Wondering what’s next for npm?Check out our public roadmap! »

    @anansi/webpack-config
    TypeScript icon, indicating that this package has built-in type declarations

    6.8.1 • Public • Published

    Production ready webpack for React

    CircleCI npm downloads npm version PRs Welcome

    A webpack 5 configuration for fast development and production ready optimizations.

    (For webpack 4 compatible config, use @anansi/webpack-config@5.4.1)

    Installation

    yarn add --dev webpack webpack-cli webpack-dev-server react-refresh @anansi/webpack-config

    or

    npm install --save-dev webpack webpack-cli webpack-dev-server react-refresh @anansi/webpack-config

    Configuration

    /webpack.config.js
    const { makeConfig } = require('@anansi/webpack-config');
    
    // See #options below
    const options = {
      basePath: 'src',
      buildDir: 'generated_assets/',
    };
    
    module.exports = { options };
    
    module.exports = makeConfig(options);

    See Options for more options to configure

    /package.json
    {
      "scripts": {
        "start": "webpack serve --mode=development",
        "build": "webpack --mode=production",
        "build:server": "webpack --mode=production --target=node",
        "build:analyze": "webpack --mode=production --env analyze",
        "build:profile": "webpack --mode=production --env profile",
        "test:pkg": "webpack --env check=nobuild"
      }
    }

    (--env requires webpack-cli >= v4)

    See cmd-line-arguments for more detail.

    See ENV to use environmental variables to customize builds

    TypeScript (optional)

    /tsconfig.js
    {
      "compilerOptions": {
        "types": ["@anansi/webpack-config/types"],
      }
    }

    Storybook 6 (optional)

    /.storybook/webpack.config.js
    const { makeStorybookConfigGenerator } = require('@anansi/webpack-config');
    const { options } = require('../webpack.config');
    
    module.exports = makeStorybookConfigGenerator(options);
    /.storybook/main.js
    module.exports = {
      core: {
        builder: "webpack5",
      },
      reactOptions: {
        fastRefresh: true,
      },
    };

    Working with webpack 5 and storybook

    Storybook currently has some issues due to being a hybrid of webpack 4 and 5. This is solved by adding some 'resolutions' to your package.json. This will only work with npm v7 and above, or yarn.

    package.json
    {
      "resolutions": {
        "webpack": "^5.0.0",
        "css-loader": "^5.0.0",
        "dotenv-webpack": "^6.0.0",
        "html-webpack-plugin": "^5.0.0",
        "style-loader": "^2.0.0",
        "terser-webpack-plugin": "^5.0.0",
        "webpack-virtual-modules": "^0.4.2"
      }
    }

    Jest (optional)

    yarn add --dev jest @anansi/jest-preset
    /jest.config.js
    module.exports = {
      preset: "@anansi/jest-preset"
    }

    Enabling react-refresh

    Install react-refresh as a dev-dependency in your project and it will automatically be detected and enabled. Be sure to use the anansi babel or include react-refresh/babel in your own babel configuration.

    yarn add --dev react-refresh

    File Support

    Production builds optimize all files for size, delivery and runtime performance

    Development optimized for quick iteration and debuggability

    • JavaScript
    • Styling (CSS)
      • SCSS with CSS modules
        • By default both .css and .scss files work as CSS Modules
          .button {
            border-radius: 6px;
            color: black;
            background: gray;
          }
          import styles from './myfile.scss';
          
          export default function MyComponent() {
            return <div className={styles.button}>Hello world</div>;
          }
        • Export SCSS variables into javascript via icss
          :export {
            bodyColor: $body-color;
            backgroundColor: $background-color;
          }
        • Provide variables/mixins to every sass file by adding sassResource
          const { makeConfig } = require('@anansi/webpack-config');
          
          const options = {
            basePath: 'src',
            buildDir: 'dist/',
            sassResources: [`${__dirname}/src/style/export.scss`],
          };
          
          module.exports = makeConfig(options);
          
          module.exports.options = options;
        • Apply global styles to every file in globalStyleDir
          const { makeConfig } = require('@anansi/webpack-config');
          
          const options = {
            basePath: 'src',
            buildDir: 'dist/',
            globalStyleDir: 'style',
          };
          
          module.exports = makeConfig(options);
          
          module.exports.options = options;
      • CSS in JS via Linaria
    • Media
      • All font formats
      • Any media files
        • svg|png|apng|jpg|avif|gif|ico|webp|cur|ani|otf|eot|woff2|woff|ttf|pdf|mp4|webm|wav|mp3|m4a|aac|oga as file urls anywhere

        • SVG as file urls or components
          import starUrl, { ReactComponent as Star } from './star.svg'
          
          const App = () => (
            <div>
              <img src={starUrl} alt="star" />
              <Star />
            </div>
          )
    • Raw string data
      • .md, .txt
    • JSON as POJO
    • HTML via html-loader

    CMD line arguments

    analyze

    If set, will build a static treemap visualization of your packages. Highly recommended to run in production mode to get accurate results.

    webpack --mode=production --env analyze

    check

    If set will run package checks to check for duplicates or ciruclar dependencies. Set equal to 'nobuild' for a standalone run where build output is not needed.

    Examples: webpack --mode=production --env check or webpack --env check=nobuild

    profile

    If set, will enable React DevTools Profiler. This feature is only available in production mode since it is enabled in development by default.

    webpack --mode=production --env profile

    readable

    Skips minification. This is useful when trying to debug production code.

    webpack --mode=production --env readable

    target

    To target node instead of default of web. This is useful when building a node server for SSR alongside the client bundle.

    webpack --mode=production --target=node

    nohash

    This is useful for diffing bundle filesizes as it removes cache busting filenames - keeping the name the same as their contents change.

    For example compressed-size-action can track bundle size changes.

    webpack --mode=production --env nohash

    ENV customization

    Environmental variable control is sometimes useful in CI pipelines to distinguish between various deploy targets.

    WEBPACK_PUBLIC_HOST = ''

    Sets domain of served files. This is useful to distinguish between different build environments that will serve assets from different locations like a CDN.

    Serves as first half of publicPath

    Note: dev mode sets its own path based assets serving is completely controlled by webpack-dev-server.

    WEBPACK_PUBLIC_PATH = '/'

    Forms the second half of the publicPath. Can be useful when assets are served in subdirectories as opposed to custom domains like in the case of CDNs.

    Options

    Pass these to makeConfig.

    libraryInclude/libraryExclude

    Regex to match libraries to include in the normal build process. This is useful for locally developed modules or yarn workspaces. Not this should point to the installed location, rather than the actual target. Note you'll need both the positive and negative regexes.

    libraryExclude defaults to /node_modules/, which will exclude libraries from expensive and potentially incorrect processing from babel loaders.

    To match all libraries in namespace @myspacespace:

    const myConfig = makeConfig({
      libraryInclude: /node_modules\/(@mynamespace\/)/,
      libraryExclude: /node_modules(?!\/(@mynamespace\/))/,
    });

    basePath = 'src'

    Marks the base directory inside the package for javascript source files. This is used to make it easy to import from the root.

    Example:

    -package.json
    -/src
      -/components
      -/pages
      -/utils
        -network.js

    Then you can do

    import fetch from 'network';

    from any file.

    babelRoot = $CWD

    babelRoot should be where the root babel configuration file is in your repo. Usually this is CWD, but while setting up a monorepo with multiple babel configurations, you may need to change this value.

    rootPath = $CWD

    Root path should be the root path of your project. Usually where your package.json and webpack.config.js are. This defaults to the current working directory you are running commands from. However, if you need to run things from another directory, you can send __dirname into this option from your webpack.config.js.

    buildDir = 'generated_assets/'

    Output directory for production build files

    serverDir: 'server_assets/'

    Output directory for production server builds. Used when using --target=node cli option.

    mode: argv?.mode || process.env.NODE_ENV

    Override the mode

    htmlOptions

    If specified, uses html-webpack-plugin to build a static html file including all assets. Using this makes development easy, and allows for cheap static deploys to CDNs like S3+cloudfront.

    Configuration options

    svgoOptions

    SVG files are optimized automatically in production builds to minimize size. SVGO is used for this. Set this to specify specific options. Alternatively set to false to disable SVGO altogether. (Note: SVGO will never run in dev mode)

    Configuration options

    svgrOptions

    SVGR enables importing SVG as a file or a component. This option allows further customizing how that is achieved.

    Configuration options

    linariaOptions

    Can configure how linaria operates. Set to false to disable linaria altogether. Note that linaria has its own config files it can use, and it is recommended to use those instead.

    Configuring Linaria

    tsconfigPathOptions

    Enabled by default. Uses any module resolution specifications like aliases in tsconfig.

    Set to false to disable; or set to object to configure the options.

    Configuring tsconfig path options

    fontPreload = 'preload' | 'prefetch'

    If specified, will preload web fonts. Choice determines the rel attribute of the link tag.

    This usually provides benefits when serving assets over HTTP/2. If using HTTP1.1 this is typically detrimental.

    bundleAnalyzerOptions

    Customize how to analyze your bundles

    manifestFilename = 'manifest.json'

    Determines the filename for the stats file that includes mappings to all filenames.

    babelLoader

    Override any babel loader specific options.

    extraJsLoaders = []

    Any extra loaders to use on JavaScript/TypeScript files.

    cssModuleOptions

    Customize css module options.

    globalStyleDir = 'style'

    Directory where only global styles are defined (no css modules)

    Set to false to disable

    sassResources

    resources option from https://github.com/shakacode/sass-resources-loader#readme

    This is useful to specify global variables and mixins to be included in every sass file.

    Working with TypeScript

    Add @anansi/webpack-config/types to the types in tsconfig.json

    {
      "compilerOptions": {
        "types": ["@anansi/webpack-config/types"],
      }
    }

    This makes all imports of supported formats typed correctly, including svgs, media files and workers.

    e.g.,

    import plain from './plain.css';
    import Worker from './my.worker.ts';
    import angleDownUrl, {
      ReactComponent as AngleDown,
    } from './angle-down-solid.svg';
    
    worker.postMessage({ message: 'rendered' });
    
    export default function MyComponent() {
      return (
        <>
          <AngleDown className={plain.svg} />
          <img src={angleDownUrl} />
        </>
      );
    }

    Working with Linaria

    When testing modules that use Linaria, it's important to add the linaria babel preset to the babel config.

    1. Install linaria: yarn add --dev @linaria/core @linaria/react @linaria/babel-preset @linaria/shaker
    2. Add @linaria to babel presets.
    module.exports = {
      presets: [
        ['@anansi', { typing: 'typescript' }],
        '@linaria',
      ],
    };

    Advanced configuration

    /webpack.config.js
    const { makeConfig } = require('@anansi/webpack-config');
    
    // See #options below
    const options = {
      basePath: 'src',
      buildDir: 'generated_assets/',
    };
    
    module.exports = { options };
    
    const baseConfig = makeConfig(options);
    
    module.exports = (env, argv) => {
      const config = baseConfig(env, argv);
    
      // Config is fully available for modification
      // Adding any custom plugins is simple
      config.plugins.push(
        new CspHtmlWebpackPlugin()
      );
    
      return config;
    }

    Install

    npm i @anansi/webpack-config

    DownloadsWeekly Downloads

    12,003

    Version

    6.8.1

    License

    BSD-3-Clause

    Unpacked Size

    218 kB

    Total Files

    21

    Last publish

    Collaborators

    • avatar
    • avatar