Neatly Positioned Magazines

    webpack-toolbox

    1.0.15 • Public • Published

    webpack-toolbox

    Collection of preconfigured wellcrafted webpack loaders and plugins, exposed in a functional way. You should be familair with webpack to understand the concepts explained below.

    summary

    Creating a webpack config file and configuring the toolchain of loaders and plugins can be a daunting task. This toolbox acceleraties the process by:

    • Installing the modules used by the toolbox (typescript, tslint, postcss, etc)
    • Providing a easy to use snippets to insert in yout webpack configuration file.

    Installaton

    Webpack toolbox installs a lot of modules and other tools, so it can take some time.

    npm i --save-dev webpack-toolbox

    Table of Contents

    Configuration file

    Webpack expects as configuration input a javascript object (or a function returning this object). The webpack-toolbox has a palette of functions to create parts of this configuration object.

    A typical webpack configuration (config.js) file using webpack-toolbox would look like this:

    const {  
         external: { wPackN_Ext },
         rule: { lint, tsc },
         plugins: { rm },
         resolve: { extentions }
     
    = require('webpack-toolbox');
     
    const { resolve } = require('path');
     
    module.exports = function(env) {
        
        return [{
            target: "node",
            entry: {
                myLib: resolve('src/lib/index.ts'),
                'myLib.min': resolve('src/lib/index.ts')
            },
            output: {
                path: resolve('dist'),
                filename: '[name].js',
                libraryTarget: 'umd2',
                library: 'MYLIB'
            },
            devtool: 'source-map',
            externals: [
                wPackN_Ext() 
            ],
            module: {
                rules: [
                    lint(),
                    tsc({ declaration: true })
                ]
            },
            plugins: [
                rm({ paths: ['lib', './'] }) 
            ],
            resolve: {
                extensions,
            },
        }];
    }

    pets

    The webpack config file doesnt use loaders directly it wraps them into rules. In case the provided rules in the toolkit do not suffice you can build your own rules with these loader snippets.

    file

    This function configures the options of the file-loader.

    const { file  } = require('webpack-toolbox').loader;
     
    const opt = {} // specify options for 'file-loader' 
     
    const fl1 = file(opt); // merges options with default 
    const fl2 = file(); // uses default options { name: '[name].[ext]' }
    /* =>
        {
            loader: 'file-loader',
            options: 
                <opt> merged with 
                { name: '[name].[ext]' }
        }
    */

    asString

    This function returns the raw-loader config snippet.

    The raw-loader returns any file as a string.

    It has no options.

    const { asString  } = require('webpack-toolbox').loader;
     
    const str = asString();  
    /* =>
        {
           loader: 'raw-loader'
        }
    */

    scss

    This function configures options for the sass-loader.

    The sass-loader transpiles an scss file to css.

    Usage:

    const {  loader: { scss }  } = require('webpack-toolbox');
     
    const opt = {}; //specifiy options here
     
    const sc1 = scss(opt);
    const sc2 = scss(); // go with default  
    /* =>
        {
           loader: 'sass-loader',
           options: 
                <opt> merged with
                { 
                 sourceMap: uid(32),
                 precision: 5 
                 }
        }
    */

    cssDependencies

    This function configures options for the css-loader. The css-loader resolves the 'import' statement in css files.

    Usage:

    const {  loader: { cssDependencies }  } = require('webpack-toolbox');
     
    const opt = { url: false}; //specify or override options here
     
    const css1 = cssDependencies(opt); // merge opt with default
    const css2 = cssDependencies(); // go with default , see below
    /*=>
    {
        loader: 'css-loader',
        options: {
           url: true,
           import: true,
           modules: true,
           minimize: false,
           sourceMap: true,
           camelCase: false,
           localIdentName: '[local]_[path][name]',
           importLoaders: 2
        }
    }
    */

    postCss

    This function configures options for the postcss-loader.

    The postcss-loader performs a number of transpilations on css files via postcss-loader plugins.

    Usage:

    const {  loader: { postCss } } = require('webpack-toolbox');
     
    const opt = {}; //specifiy options here
     
    const css1 = postCss(opt); //merges opt with default
    const css2 = postCss(); //Go with default only , see below
    /*
    {
        loader: 'postcss-loader',
        options: {
               plugins: {
                   postcss-preset-env':{
                       stage: 3,
                       browsers: 'last 2 versions',
                       features:{
                           'nesting-rules': true
                       }
                   },
                   autoprefixer: {},
                   'postcss-sorting': {
                       'properties-order': 'alphabetical'
                    }
                },
                sourceMap: true
            }
        }
    }
    */

    embedCss

    TODO: This function configures options for the style-loader. TODO: check the dock what is the diff with "textextractor". The style-loader inserts css in the html form via <style> tags.

    Usage:

    const { loader: { embedCss }  } = require('webpack-toolbox');
     
    const opt = {}; //specifiy options here
     
    const emb1 = embedCss(opt); //merges opt with default
    const emb2 = embedCss(); // go with default only , see below
    /*==>
    {
     
        loader: 'style-loader',
        options: 
            <opt> is merged with 
             {
                sourceMap: true
             }
    }
    */

    tslint

    This function configures options for the tslint-loader.

    The tslint-loader validates (and optionally fixes) code styling.

    Apply the tslint loader as preLoader in your webpack configuration.

    Notes:

    • ⚠️ this loader has severe performance problems since mid 2017 issue.
    • --prefix is depricated, use --project instead see note.

    Usage:

    const { resolve } = require('path');
    const { loader: { tsl }  } = require('webpack-toolbox');
     
    const opt = { 
        configFile: resolve('my_tsconfig_test.json') ,
        emitErrors: false,
    }; 
     
    const t1 = tsl(opt); //merges opt with default
    const t2 = tsl();// just use default, see below
    /*==>
     loader: 'tslint-loader',',
     options: 
        <opt> merged with
        configFile: resolve('tslint.json'),
        emitErrors: true,
        failOnHint: true,
        fix: true,
        tsConfigFile: resolve('tsconfig.webpack.json')
    */

    tsl

    This function configures options for the ts-loader.

    The ts-loader transpiles typscript files to javascript.

    Note: the configFile (points to tsconfig.json) property of the options object is default set to <project working directory>/tsconfig.webpack.json

    decl

    declare function  tsl(loaderOptions): {...} 
    const { resolve } = require('path');
    const { loader: { tsl }  } = require('webpack-toolbox');
     
    const opt = { configFile: resolve('tsconfig_test.json') }; 
     
    const t1 = tsl(opt); //merges opt with default
    const t2 = tsl(); //go with default only , see "options" below
    /*==>
    {
        loader: 'ts-loader',
        options: 
            <opt> merged with  
            {
                transpileOnly: false,
                happyPackMode: false, //set this to true later, see doc,
                logInfoToStdOut: true, //stderr to stdout
                configFile: resolve('tsconfig.webpack.json'),
            }
    }
    */

    Rule snippets

    Rules are matched to requests when modules are created. For all the configuration options for webpack rules see module.rule doc. Rules apply loaders to transform files (modules).

    tsc

    This function creates a webpack Object configuration snippet for transpilation of typescript source files. tsc configures the loader tsl.

    decl

    function tsc(loaderOptions, ruleOptions): {..};

    Usage:

    const wbtk = require('webpack-toolkit');
     
    const { rule: { tsc } } =  wbtk;
     
    const loaderOptions = {}; // go with defaults
    const ruleOptions = {}; // got with defaults 
     
    const rule1 = tsc(
        loaderOptions, /* loader options, passed directly to `tsl`*/
        ruleOptions, /* define module.rule properties */
    );
    /*=>
    {
       test: /\.ts$/i, 
       use: {
            transpileOnly: false,
            happyPackMode: false, //set this to true later, see doc,
            logInfoToStdOut: true, //stderr to stdout
            configFile: resolve('tsconfig.webpack.json'),
       }
    }
    */

    sql

    This function creates a webpack Object configuration snippet for the loading the text of an sql file as a string in your source code.

    sql configures the loader asString.

    decl

    function sql(ruleOptions): {..};

    Usage:

    const wbtk = require('webpack-toolkit');
     
    const { rule: { sql } } =  wbtk;
     
    const ruleOptions = { issuer: 'index.js' };  
     
    const rule1 = sql(
        ruleOptions /* define module.rule properties */
    );
    /*=>
    {
        test: /\.sql$/i,
        use: asString(),
        issuer: 'index.js'
    }
    */

    gql

    This function creates a webpack Object configuration snippet for the loading the text of an gql file (GraphQL) as a string in your source code.

    gql configures the loader asString.

    decl

    function gql(ruleOptions): {..};

    Usage:

    const wbtk = require('webpack-toolkit');
     
    const { rule: { gql } } =  wbtk;
     
    const ruleOptions = { resourceQuery: /inline/  };  
     
    const rule1 = gql(
        ruleOptions /* define module.rule properties */
    );
    /*=>
    {
        test: /\.gql$/i,
        use: asString(),
        resourceQuery: /inline/
    }
    */

    fonts

    This function creates a webpack Object configuration snippet for emitting a font file via the file-loader. Either emit the the font file, it into the bundle or reference it via an url.

    decl

    function fonts(loaderOptions, ruleOptions): {..};

    Usage:

    const wbtk = require('webpack-toolkit');
     
    const { rule: { fonts } } =  wbtk;
     
    const loaderOptions = { emitfile: true }; //emit the fontfile with the bundle
    const ruleOptions = { resourceQuery: /inline/  };  
     
    const rule1 = fonts(
        loaderOptions,
        ruleOptions 
    );
    /*=>
    {
        test: /(\.svg|\.woff|\.woff2|\.[ot]tf|\.eot)$/,
        use: // result of  file( { emitFile: true } ) 
            { 
                loader: 'file-loader',
                options:{ 
                    name: '[name].[ext]',
                    emitfile: true
                }
            }
        resourceQuery: /inline/
    }
    */

    emitJsCss

    This function creates a webpack Object configuration snippet for emitting a css/js file that will not be part of the bundle (for example 3rd party vendor). It uses the file-loader. require-ing the file in your js file will return the uri of the css/js file.

    decl

    function emitJsCss(loaderOptions, ruleOptions): {..};
    • loaderOptions are passed directly to the file function.
    • ruleOptions configure the specific webpack rule
    ruleOptions.include leads to: Rule.include
    undefined["/src/lib/vendor/cdn"]
    []undefined
    ["some valid dir"]["some valid dir"]

    Usage:

    const wbtk = require('webpack-toolkit');
    const { resolve } = require('path');
     
    const { rule: { emitJsCss } } =  wbtk;
     
    const loaderOptions = { emitfile: true }; //emit the fontfile with the bundle
    const ruleOptions = { include: [ resolve('src/vendor/d3'), resolve('src/vendor/react-dom') ] };  
     
    const rule1 = emitJsCss(
        loaderOptions,
        ruleOptions 
    );
    /* =>
      { 
          test: /\.(js|css)$/
          include: ['src/vendor/d3', 'src/vendor/react-dom' ]
          use: {
              loader: 'file-loader',
              options:{ 
                  name: '[name].[ext]',
                  emitfile: true
              }
          }
      }
    */

    embedSqlGql

    This function creates a webpack Object configuration snippet for embedding an sql/gql file that will be loaded into the final bundle with require. It uses the raw-loader via asString.

    decl

    function embedSqlGql(ruleOptions): {..};

    Usage:

    const wbtk = require('webpack-toolkit');
    const { resolve } = require('path');
     
    const { rule: { embedSqlGql } } =  wbtk;
     
    const ruleOptions = { include: [ resolve('src/vendor/d3'), resolve('src/vendor/react-dom') ] };  
     
    const rule1 = embedSqlGql( ruleOptions );
    /* =>
      { 
          test: /\.([sg]ql)$/,
          include: ['src/vendor/d3', 'src/vendor/react-dom' ]
          use: {
              loader: 'raw-loader'
          }
      }
    */

    cssFiles

    Function to provide a rule to transpile scss/sass files to css files. Combines 4 loader-snippet generating functions: 1) embedCss, 2) cssDependencies, 3) postcss, 4) scss.

    decl

    function cssFiles(ruleOptions): {..};

    Because cssFiles configures several loaders and the rule itself, the "options" are partitioned into several subobjects:

       declare type ruleOptions {
           embed: {...}, // for embedCss(embed)
           depend: {...}, // for cssDependencies(depend)
           post: {...}, // for postCss(post)
           oscss: {...} // for scss(oscss)
           rule: {...} // contains options for this rule
       }
    • ruleOptions.embed: options for embedCss.
    • ruleOptions.depend: options for cssDependencies.
    • ruleOptions.post: options for postCss.
    • ruleOptions.scss: options for [scss][#scss].
    • ruleOptions.rule: options for this rule itself, see webpack rule.

    This rule will always have these unchangable properties fixed:

    Usage:

    const wbtk = require('webpack-toolkit');
    const { resolve } = require('path');
     
    const { rule: { cssFiles } } =  wbtk;
     
    const ruleOptions = { 
        embed: { sourceMap: true },
        depend: { camelCase: false, },
        post: { 
            plugins:
                'postcss-sorting': {
                     'properties-order': 'alphabetical'
                }
            }
        },
        scss:{},// go with defaults
        rule: {
            include: [ resolve('src/vendor/d3'), resolve('src/vendor/react-dom') ] };
        }
    }
     
    const rule = cssFiles( ruleOptions );
    /* =>
        include: [ resolve('src/vendor/d3'), resolve('src/vendor/react-dom') ] },
        test: [/\.s[ca]ss$/, /\.css$/],
        use: [
            { //embedCss
                loader: 'style-loader',
                options: { sourceMap: true }
            },    
            { //depend
                loader: 'css-loader'',
                   options: { camelCase: false, }
     
            },
            { //post
                loader:'postcss-loader',
                options:{
                    plugins: {
                        'postcss-sorting': {
                            'properties-order': 'alphabetical'
                        }
                    }
                }
            },
            { //scss
                loader: 'sass-loader',
                options: { 
                    sourceMap: uid(32),
                    precision: 5 
                }
            }
        ]
    }
    */

    tslinter

    This function creates a rule snippet to check typescript source code using the tslint loader-snippet generating function.

    decl

    function tslinter(loaderOptions, ruleOptions): {...};
    • loaderOptions are passed directly to the tslint function.
      • property typecheck is always set to false.
    • ruleOptions configure the specific webpack rule
    const wbtk = require('webpack-toolkit');
     
    const { rule: { tslinter } } =  wbtk;
     
    const ruleOptions = {};
    const loaderOptions = {};
    const rule = tslinter( loaderOptions, ruleOptions );
    /*=>
    {
        enforce: 'pre',
        test: /\.tsx?$/,
        use: {
                loader: 'tslint-loader',
                options: {
                    typeCheck:  false,
                    configFile: // by default, a "module internal" tslint.json is used,
                    emitErrors: true,
                    failOnHint: true,
                    fix: true,
                    tsConfigFile: // by default, a "module internal" tsconfig.json is used. 
                }
        }
    }
    */

    Plugin snippets

    These functions create configuration snippets, one for the plugin part of webpack config file.

    extractText

    This function will returns a configuration snippets for to plugin plugin-extract-text-webpack.

    The plugin-extract-text-webpack extracts text (for example css) from the final bundle into a seperate file (handy for parallel loading).

    To use this plugin you need to configure the plugin itself of course and also a rule referencing the plugin.

    Hence this function's sole option argument is partitioned into 2 parts: rule and plugin.

    decl

    declare function extractText(options: { rule:{...}, plugin:{...} }) : { rule: {...}, plugin: {...} };

    on input:

    options argument object has 2 parts (properties):

    • plugin: options for this plugin see extract-text-webpack.
      • plugin.filename: will default to styles.css if not specified.
    • rule: options to configure the rule snippet.
      • rule.test: will default to /\.css$/ if not specified.
      • rule.loaders: an array of loaders for the extract-text-webpack to use. Defaults to ['css-loader', 'postcss-loader'].

    on output:

    The returned value from extractText mirrors its input:

    • plugin: the plugin element that needs to be added to the plugin part of the config.
    • rule: A rule snippet that must be added to the rule part of the config.

    Usage:

    const wbtk = require('webpack-toolkit');
    const { plugin: { extractText } } = wbtk;
     
    const options =  {
        plugin: { 
            filename: 'mystyle.css'
        }
        rule: {} // go with defaults
    };
     
    const confextrText = extractText(options); // default is 'extract-text-webpack-plugin'
    /*=>
        plugin: result of "new  ExtractTextPlugin( { filename: 'mystyle.css' })"
        rule: {
            test: /\.css$,
            rule: ExtractTextPlugin.extract(['css-loader', 'postcss-loader'])
        }
    */
     
    // incomplete webpack config object
    module.exports = {
        .
        .
        module: {
            rules: [ confextrText.rule, /* other rules */ ]
        }
        .
        .
        plugins: [
            confextrText.plugin, /* other plugins */
        ]
    };

    miniCssExtract

    This function creates a plugin snippet that extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.

    It builds on top of a new webpack v4 feature (module types).

    Compared to the extractText ( aka extract-text-webpack-plugin )

    • Async loading
    • No duplicate compilation (performance)
    • Easier to use
    • Specific to CSS

    decl

    declare function miniCssExtract(options: { rule:{...}, plugin:{...} }) : { rule: {...}, plugin: {...} };

    on input:

    options argument object has 2 parts (properties):

    • plugin: options for this plugin see mini-css-extract-plugin.
      • plugin.filename: will default to [name].[hash].css if not specified.
      • plugin.chunkFilename: will default to '[id].[hash].css' if not specified.
    • rule: options to configure the rule snippet.
      • rule.test: will default to /\.(sa|sc|c)ss$/ if not specified.
      • rule.loaders: an array of loaders will be merged to get the result array [MiniCssExtractPlugin.loader, ...rule.loaders]

    on output:

    The returned value from miniCssExtract mirrors its input:

    • plugin: the plugin element that needs to be added to the plugin part of the config.
    • rule: A rule snippet that must be added to the rule part of the config.

    Usage:

    const wbtk = require('webpack-toolkit');
    const { plugin: { miniCssExtract } } = wbtk;
     
    const options =  {
        plugin: { 
            filename: '[name].css'
        }
        rule: {
            loaders:['css-loader']
        } // go with defaults
    };
     
    const confextrText = miniCssExtract(options);
    /*=>
    {
        plugin: new MiniCssExtractPlugin({
                filename: "[name].css",
                chunkFilename: "[id].css"
            })
        ,
        rule: {   
            test: /\.(sa|sc|c)ss$/,
            use: [
                MiniCssExtractPlugin.loader,
                "css-loader"
            ]
        }
    }
    */
     
    // incomplete webpack config object
    module.exports = {
        .
        .
        module: {
            rules: [ confextrText.rule, /* other rules */ ]
        }
        .
        .
        plugins: [
            confextrText.plugin, /* other plugins */
        ]
    };

    rm

    Mirrors unix rm shell command. This function creates a plugin snippets removing/deleting your build folder(s). This function configures the uses the clean-webpack-plugin.

    decl

    declare function rm(options): {...};

    on input

    • options options for the clean-webpack-plugin.
      1. property options.paths: array of 1 or more paths that needs to be deleted
      2. property options.root: defaults to <projectdir>/dist if root is not specified in options.
      3. property options.* (* is wildcard property other then paths in "1.") are passed to the clean-webpack-plugin

    on output

    returns a snippet for the config.plugin section of the webpack plugin.

    Usage:

    const wbtk = require('webpack-toolkit');
    const { plugin: { rm } } = wbtk;
     
    const options = {
      path: 'dist',
      // Write logs to console.
      verbose: true,
      // Use boolean "true" to test/emulate delete. (will not remove files).
      // Default: false - remove files
      dry: false
    };
     
    const cleanPluginSnippet = rm(options);
    /*=>
      new CleanWebpackPlugin( 'dist', { verbose: true, dry: false });
    */
     
    module.exports = {
        plugins: [
            cleanPluginSnippet, /*... other plugins */
        ]
    };

    defines

    This function will returns a configuration snippet for to plugin webpack.DefinePlugin. The plugin works much like C language #define, replacing strings in code before "transpiling" (compiling in C context).

    decl

     declare function defines( options ): {...}

    options is a JS object with key/value mapping, it will search the sourcefiles for the key string and replace it with the value string

    Usage:

    const wbtk = require('webpack-toolkit');
    const { plugin: { defines } } = wbtk;
     
    const options = {
      PRODUCTION: JSON.stringify(true),
      VERSION: JSON.stringify('5fa3b9'),
      BROWSER_SUPPORTS_HTML5: true,
    };
     
    const defineSnippet = defines(options);
     
    module.exports = { //incomple webpack config file for succinctness
        .
        plugins: [
            .
            defineSnippet,
            /*... other plugins */
            .
        ]
        .
    };

    uglify

    This function will returns a configuration snippet for to plugin UglifyJS.

    decl

     declare function uglify(options): {....}

    Look here for a full list of options.

    default options

    The following properties of the options object are set to the following default if not specified:

    • cache: true
    • include: /.min.js$/
    • extractComments: true
    • sourceMap: true
    • uglifyOptions.compress: true

    Usage:

    const wbtk = require('webpack-toolkit');
    const { plugin: { uglify } } = wbtk;
     
    module.exports = { //incomple webpack config file for succinctness
        .
        plugins: [
            .
            uglify({
                sourceMap: false
            }),// go with fixed defaults
            /*... other plugins */
            .
        ]
        .
    };

    wPackNodeExternals

    This function will return a configuration snippet for to plugin webpackNodeExternals. The plugin manages what is included and/or excluded in the final webpack bundle.

    decl

    declare function wPackNodeExternals(options): { ...}

    See [here][plugin-externals-options for a all options.

    default options

    These properties of the options object are set to the following defaults if not specified:

    • whitelist: , the whitelist of modules (will be included into the final bundle)
    • importType: 'commonjs', Externalize as commonjs
    • modulesDir: 'node_modules' (directory of node_modules)
    • modulesFromFile: false, do not use package.json to get node_module names

    Usage:

    const wbtk = require('webpack-toolkit');
    const { plugin: { wPackNodeExternals } } = wbtk;
     
    module.exports = { //incomple webpack config file for succinctness
        .
        plugins: [
            .
            wPackNodeExternals({
                whitelist:[ 'debug', 'ms' ] // include the modules "debug" and "ms" in the final bundle
            }),
            /*... other plugins */
            .
        ]
        .
    };
     

    hmtl

    Examples

    TODO

    Install

    npm i webpack-toolbox

    DownloadsWeekly Downloads

    15

    Version

    1.0.15

    License

    GPL-3.0

    Unpacked Size

    84.4 kB

    Total Files

    11

    Last publish

    Collaborators

    • jacobbogers