Home  >  Article  >  Web Front-end  >  A brief introduction to the webpack packager

A brief introduction to the webpack packager

零下一度
零下一度Original
2017-06-26 10:37:231751browse

Concept

Webpack is a module packager for modern javascript applications.

When webpack processes your application, it recursively builds a dependency graph (containing every module your application needs), and then packages these modules into a handful of Budle files (usually There is only one, which will be loaded by the browser, depending on the project situation).

This is an incredible configuration, but before you get started, you only need to understand four core concepts: entry, output, loaders, and plugins.

Configuration Object Options
webpack.config.js

const path = require('path');

module.exports = {
  // click on the name of the option to get to the detailed documentation
  // click on the items with arrows to show more examples / advanced options

  entry: "./app/entry", // string | object | array
  // Here the application starts executing
  // and webpack starts bundling

  output: {
    // options related to how webpack emits results

    path: path.resolve(__dirname, "dist"), // string
    // the target directory for all output files
    // must be an absolute path (use the Node.js path module)

    filename: "bundle.js?1.1.11", // string
    // the filename template for entry chunks

    publicPath: "/assets/", // string
    // the url to the output directory resolved relative to the HTML page

    library: "MyLibrary", // string,
    // the name of the exported library

    libraryTarget: "umd", // universal module definition
    // the type of the exported library

    /* Advanced output configuration (click to show) */
  },

  module: {
    // configuration regarding modules

    rules: [
      // rules for modules (configure loaders, parser options, etc.)

      {
        test: /\.jsx?$/,
        include: [
          path.resolve(__dirname, "app")
        ],
        exclude: [
          path.resolve(__dirname, "app/demo-files")
        ],
        // these are matching conditions, each accepting a regular expression or string
        // test and include have the same behavior, both must be matched
        // exclude must not be matched (takes preferrence over test and include)
        // Best practices:
        // - Use RegExp only in test and for filename matching
        // - Use arrays of absolute paths in include and exclude
        // - Try to avoid exclude and prefer include

        issuer: { test, include, exclude },
        // conditions for the issuer (the origin of the import)

        enforce: "pre",
        enforce: "post",
        // flags to apply these rules, even if they are overridden (advanced option)

        loader: "babel-loader",
        // the loader which should be applied, it'll be resolved relative to the context
        // -loader suffix is no longer optional in webpack2 for clarity reasons
        // see webpack 1 upgrade guide

        options: {
          presets: ["es2015"]
        },
        // options for the loader
      },

      {
        test: "\.html$",

        use: [
          // apply multiple loaders and options
          "htmllint-loader",
          {
            loader: "html-loader",
            options: {
              /* ... */
            }
          }
        ]
      },

      { oneOf: [ /* rules */ ] },
      // only use one of these nested rules

      { rules: [ /* rules */ ] },
      // use all of these nested rules (combine with conditions to be useful)

      { resource: { and: [ /* conditions */ ] } },
      // matches only if all conditions are matched

      { resource: { or: [ /* conditions */ ] } },
      { resource: [ /* conditions */ ] },
      // matches if any condition is matched (default for arrays)

      { resource: { not: /* condition */ } }
      // matches if the condition is not matched
    ],

    /* Advanced module configuration (click to show) */
  },

  resolve: {
    // options for resolving module requests
    // (does not apply to resolving to loaders)

    modules: [
      "node_modules",
      path.resolve(__dirname, "app")
    ],
    // directories where to look for modules

    extensions: [".js?1.1.11", ".json", ".jsx", ".css?1.1.11"],
    // extensions that are used

    alias: {
      // a list of module name aliases

      "module": "new-module",
      // alias "module" -> "new-module" and "module/path/file" -> "new-module/path/file"

      "only-module$": "new-module",
      // alias "only-module" -> "new-module", but not "module/path/file" -> "new-module/path/file"

      "module": path.resolve(__dirname, "app/third/module.js?1.1.11"),
      // alias "module" -> "./app/third/module.js?1.1.11" and "module/file" results in error
      // modules aliases are imported relative to the current context
    },
    /* alternative alias syntax (click to show) */

    /* Advanced resolve configuration (click to show) */
  },

  performance: {
    hints: "warning", // enum
    maxAssetSize: 200000, // int (in bytes),
    maxEntrypointSize: 400000, // int (in bytes)
    assetFilter: function(assetFilename) {
      // Function predicate that provides asset filenames
      return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
    }
  },

  devtool: "source-map", // enum
  // enhance debugging by adding meta info for the browser devtools
  // source-map most detailed at the expense of build speed.

  context: __dirname, // string (absolute path!)
  // the home directory for webpack
  // the entry and module.rules.loader option
  //   is resolved relative to this directory

  target: "web", // enum
  // the environment in which the bundle should run
  // changes chunk loading behavior and available modules

  externals: ["react", /^@angular\//],
  // Don't follow/bundle these modules, but request them at runtime from the environment

  stats: "errors-only",
  // lets you precisely control what bundle information gets displayed

  devServer: {
    proxy: { // proxy URLs to backend development server
      '/api': 'http://localhost:3000'
    },
    contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location
    compress: true, // enable gzip compression
    historyApiFallback: true, // true for index.html upon 404, object for multiple paths
    hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
    https: false, // true for self-signed, object for cert authority
    noInfo: true, // only errors & warns on hot reload
    // ...
  },

  plugins: [
    // ...
  ],
  // list of additional plugins


  /* Advanced configuration (click to show) */
}

The purpose of this document is to provide a high-level outline of these concepts , while providing links to specified use cases for detailed concepts.

Entry

webpack creates a dependency graph of all your applications. The starting point of this dependency graph is the known entry point. This entry point tells webpack where to start and package it based on a known dependency graph. You can think of your application's entry point as the context root or the first file that starts your application.

Define the entry point in the entry attribute of the webpack configuration object. A simple example is as follows:

module.exports = {
  entry: './path/to/my/entry/file.js'
};

There are several ways to declare the entry attribute:

1. Single entry syntax

const config = {
  entry: './path/to/my/entry/file.js'
};

module.exports = config;

2. Object syntax

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};

3. Multi-page application

const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};

Output

Once you package all the code, you still need to tell webpack where to package it. The output attribute tells webpack how to treat your code.

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  }
};

In the above example, we use the output.filename and output.path properties to tell webpack the packaged file name and path

More configuration items

Loaders

The purpose of this configuration item is to let webpack focus on all the code of your project instead of the browser (this does not mean that they will be packaged together). webpack treats each file (.css, .html, .scss, .jpg, etc.) as a module. However, webpack only knows javascript.

Loaders in webpack will convert these files into modules and add them to your dependency graph.

At a high level, there are two purposes in your webpack configuration:
1. Identify what files should be converted with a certain loader.
2. The converted files can be added to your dependency graph.

const path = require('path');

const config = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  },
  module: {
    rules: [
      {test: /\.(js|jsx)$/, use: 'babel-loader'}
    ]
  }
};

module.exports = config;

The above configuration defines a rulues attribute for a separate module. This module has two attributes: test and use. This tells webpack to compile the following things:
When using require() or import statements, files with a .js or .jsx suffix in the path are converted and packaged using babel-loader.

More configuration items

Plugins

Because the loader only performs conversions on a per-file basis, plug-ins are the most commonly used (but not limited to) optimization behavior, and you Custom functions can be defined in editors or blocks of your packaged modules (etc.).
The webpack plug-in system is extremely powerful and customizable.

To use a plugin, you just require() and add it to the plugins array. More plugins can be customized with options. Since you can use a plugin multiple times in a configuration for different purposes, you will need to create a new instance.

const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const path = require('path');

const config = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  },
  module: {
    rules: [
      {test: /\.txt$/, use: 'raw-loader'}
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

module.exports = config;

webpack provides many out-of-the-box plugins! More information can be obtained from our plugin list.

Using plugins in a webpack configuration is simple, however there are many usages worth exploring further.

More configuration items

Simple example

var path = require('path');
var webpack = require('webpack');

var env = process.env.NODE_DEV;

var config = {
    entry: {
        consumer: './consumer/index.js',
        admin: './admin/index.js',
        // jquery: ['jquery']
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/dist/',
        filename: '[name].bundle.js'
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: 'style-loader!css-loader' },
            { test: /\.less$/, loader: 'less-loader!style-loader!css-loader' },
            { test: /\.sass$/, loader: 'sass-loader!style-loader!css-loader' },
            { test: /\.(woff|woff2|eot|ttf|otf)$/i, loader: 'url-loader?limit=8192&name=[name].[ext]' },
            { test: /\.(jpe?g|png|gif|svg)$/i, loader: 'url-loader?limit=8192&name=[name].[ext]' },
            {
                test: /\.jsx?$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                include: __dirname,
                options: {
                    presets: ['es2015', 'react']
                },
            },
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/,
                include: __dirname
            },
            {
                test: /\.coffee$/,
                loader: 'coffee-loader',
                exclude: /node_modules/,
                include: __dirname
            }
        ]
    },
    //devtool: 'source-map',
    //指定根路径
    context: __dirname,
    //这里枚举的后缀名,在require时可以省略
    resolve: {
        extensions: ['.js', '.jsx', '.json', '.ts', '.tsx', '.css']
    },
    plugins: [
        // 这里声明的变量是全局的,可以在所有的js中使用,可以避免写一堆的require
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            'window.$': 'jquery',
            'React': 'react',
            'ReactDOM': 'react-dom'
        }),
        // new webpack.optimize.CommonsChunkPlugin({
        //     // 与 entry 中的 jquery 对应
        //     name: 'jquery',
        //     // 输出的公共资源名称
        //     filename: 'jquery.min.js',
        //     // 对所有entry实行这个规则
        //     minChunks: Infinity
        // }),
        // new webpack.NoEmitOnErrorsPlugin()
    ],
    //在html页面中使用script标签引入库,而不是打包到*.bundle.js文件中
    externals: {
        jquery: 'jQuery',
        react: 'React',
        'react-dom' : 'ReactDOM'
    }
};

//如果是生产环境,要最小化压缩js文件
if (env === 'production') {
    //打包时对js文件进行最小化压缩
    config.plugins.push(new webpack.optimize.UglifyJsPlugin({
        mangle: {
            except: ['$super', '$', 'exports', 'require']
            //以上变量‘$super’, ‘$’, ‘exports’ or ‘require’,不会被混淆
        },
        compress: {
            warnings: false
        }
    }));
    //消除压缩后的文件在界面引用时发出的警告
    config.plugins.push(new webpack.DefinePlugin({
        'process.env': {
            NODE_ENV: JSON.stringify('production')
        }
    }));
}

module.exports = config;

The above is the detailed content of A brief introduction to the webpack packager. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn