安装

使用 npm 的形式来安装到全局:
$ npm install webpack -g
个人还是推荐直接安装到项目目录下:
$ npm init
$ npm install webpack --save-dev

配置

在项目根目录新建webpack.config.js文件, 在文件中写入:

module.exports = {
  //各种配置
}

下面来详细说明, 上面代码中的各种配置

context - 基本目录

基本目录(绝对路径)用于解决entry选项, 默认值: process.cwd()

{
    context: __dirname + "/app",
}

entry - 入口文件

如果您传递了一个字符串:字符串将被解析为一个模块,该模块在启动时加载。
如果你通过一个数组:所有的模块都在启动时加载。最后一个是导出的。
单入口:

{
    entry: './src/app.js'
}
{
    entry: ["./entry1", "./entry2"]
}

多入口:

{
    entry: {
        page1: "./page1",
        page2: ["./entry1", "./entry2"]
    }
}

output - 输出文件

虽然entry可以配置多个入口点,但是只能有一个输出配置, output配置项是一个对象,包括一下配置:

output.filename - 输出文件名

entry 配置为单入口时

{
  output: {
    filename: 'bundle.js'
  }
}

entry配置为多入口时

  • [name] 被替换为块的名称
  • [hash] 被编译的哈希所取代
  • [chunkhash] 是由数据块的哈希取代
{
  output: {
    filename: '[name].js'
  }
}

这里也可以指定目录, 如: 'static/js/[name].[hash].js', 那么js文件将生成到static/js目录下

output.path - 输入目录

该配置为绝对目录

{
  output: {
    filename: '[name].js',
    path: __dirname + '/built'
  }
}

output.publicPath - 前缀路径

如果你最后想将webpack生成的文件放到cdn, 那么必须配置此项

{
  output: {
    path: __dirname + '/built',
    publicPath: "/assets/"
  }
}
{
  output: {
    path: __dirname + '/built',
    publicPath: "http://www.xxx.com/assets/"
  }
}

output.chunkFilename

非输入块的文件输出的文件名

  • [id] 被替换为块的id
  • [name] 被替换为块的名称
  • [hash] 被编译的哈希所取代
  • [chunkhash] 由数据块的哈希取代
{
  output: {
    filename: '[name].js',
    chunkFilename: '[name].[chunkhash].chunk.js',
    path: __dirname + '/built'
  }
}

这里也可以指定目录, 如: 'static/js/[name].[chunkhash].chunk.js', 那么js文件将生成到static/js目录下

output.sourceMapFilename - sourceMap输出文件名

这个用处不大,可以忽略不配置

  • [file] 被JavaScript文件的文件名替换
  • [id] 被替换为块的身份证
  • [hash] 被编译的哈希所取代
{
  output: {
    filename: '[name].js',
    sourceMapFilename: '[file].sourceMap.js',
    path: __dirname + '/built'
  }
}

output.devtoolModuleFilenameTemplate

默认或者不配置即可

默认值 (devtool=[inline-]source-map): "webpack:///[resource-path]"
默认值 (devtool=eval): "webpack:///[resource-path]?[loaders]"
默认值 (devtool=eval-source-map): "webpack:///[resource-path]?[hash]"

output.devtoolFallbackModuleFilenameTemplate

默认或者不配置即可

默认值: "webpack:///[resourcePath]?[hash]"

output.devtoolLineToLine

默认或者不配置即可

默认值: 禁用

output.hotUpdateChunkFilename

默认或者不配置即可

默认值: "[id].[hash].hot-update.js"

output.hotUpdateMainFilename

默认或者不配置即可

默认值: "[hash].hot-update.json"

output.jsonpFunction

默认或者不配置即可

默认值: "webpackJsonp"

output.hotUpdateFunction

默认或者不配置即可

默认值: "webpackHotUpdate"

output.library

如果设置,将导出包作为库。 output.library作为名字。
如果您正在编写一个库,并希望将其发布为单个文件, 那么可以设置该项

output.libraryTarget

导出库的格式

"var"
"this"
"commonjs"
"commonjs2"
"amd"
"umd"

module - 模块

module.loaders - 加载器

loaders整体有一个数组,单个配置是一个对象, 包括以下配置:

test: 匹配规则
exclude: 排除目录
include: 包含目录
loader: 加载器(字符串)
loaders: 加载器(数组)

{
    module: {
        loaders: [
            test: /\.jsx$/,
            include: [
                path.resolve(__dirname, "app/src"),
                path.resolve(__dirname, "app/test")
            ],
            exclude: /node_modules/,
            loader: "babel-loader"
        ]
    }
}

注: 加载器后面的-loader可以省略写成loader: "babel"

一些常用文件及加载器名称

文件类型 加载器
.js babel-loader
.ts ts-loader
.coffee coffee-loader coffee-redux-loader
.jsx jsx-loader react-hot-loader!jsx-loader
.json .json5 json-loader json5-loader
.txt raw-loader
.css style-loader!css-loader style-loader!css-loader!autoprefixer-loader
.less style-loader!css-loader!less-loader
.scss style-loader!css-loader!scss-loader
.styl style-loader!css-loader!stylus-loader
.png .jpg .jpeg .gif .svg file-loader url-loader
.woff .ttf file-loader url-loader
.wav .mp3 file-loader url-loader
.mpeg .mp4 .webm .ogv file-loader
.html html-loader
.md .markdown html-loader!markdown-loader
.pug .jade pug-loader
.hbs .handlebars handlebars-loader

module.preLoaders, module.postLoaders

该配置格式和loaders一样, 可以用于编译前检测eslint

{
    module: {
        loaders: [
            test: /\.js|\.jsx$/,
            loader: 'eslint-loader'
        ]
    }
}

resolve

resolve.alias - 设置别名

{
  resolve: {
    alias: {
      js: path.join(__dirname, "src/scripts")
    }
  }
}

设置别名后, 你想require('src/scripts/app.js')只需要写成require('js/app.js')即可

resolve.root - 默认搜索路径

包含模块的目录(绝对路径)。也可以是一个目录数组。
此设置应用于将单个目录添加到搜索路径中。

{
  resolve: {
    root: [
      path.resolve('./app/modules'),
      path.resolve('./vendor/modules')
    ]
  }
}
`

resolve.modulesDirectories

默认或者不配置即可

默认值: ["web_modules", "node_modules"]

resolve.fallback

webpack没有在resolve.root 或者resolve.modulesDirectories找到的模块的一个目录(或者目录绝对路径的数组

resolve.extensions

应用于解决模块的扩展数组, 配置后, 数组里的扩展名在require时可以省略

默认值: ["", ".webpack.js", ".web.js", ".js"]

{
    resolve: {
        extensions: ['', '.js', '.jsx'],
    }
}

resolve.packageMains

默认或者不配置即可

默认值: ["webpack", "browser", "web", "browserify", ["jam", "main"], "main"]

resolve.packageAlias

默认或者不配置即可

resolve.unsafeCache

默认或者不配置即可

默认值: []

resolveLoader

该配置和resolve类似, 只不过是作用于loaders

resolveLoader.moduleTemplates

默认或者不配置即可

默认值: ["-webpack-loader", "-web-loader", "-loader", ""]

{
    resolveLoader: {
        moduleTemplates: ['*-loader']
    }
}

externals

指定依赖关系

{
    externals: {
        'jquery': 'jQuery'
    }
}

当jQuery为cdn直接在html中引用时, 必须配置此项

target

"web" 在web中使用(默认)
"node" 在nodejs中使用
"webworker"
"async-node"
"node-webkit"
"electron"

如果webpack打包后的代码需要在nodejs中运行, 该项需要配置成node

bail

报告第一个错误为硬性错误, 值为true或者false

profile

定时在每个模块捕捉信息

cache

缓存生成模块和和chunks来提高混合增l量编译时的性能。
启用watch模式会默认启动它。
可以传入 false禁用它。
你可以传递一个对象启用它并且让webpack把传递的对象作为缓存。用这种办法,你可以在混合编译器的编译回调中共享缓存。注意:不要在多配置的回调中共享缓存。

watch

进入监控模式,重建变化的文件

debug

把loader的模式切到debug

devtool

选一个开发工具来加快调试

eval 每个模块都用eval执行
source-map 触发SourceMap,详情看output.sourceMapFilename
hidden-source-map 同上,但不会在包中添加引用注释。
inline-source-map SourceMap被作为dataurl加入到js文件中。
eval-source-map 每个模块都用eval执行,并且SourceMap被作为dataurl加入到eval中。
cheap-source-map 没有映射的sourcemap,loaders的sourcemap不会启用。
cheap-module-source-map 没有映射的sourcemap,sourcemap就简单的映射到每一行。

{
    devtool: "#inline-source-map"
}

devServer

用来配置 webpack-dev-server 的一些行为

{
    devServer: {
        contentBase: "./build",
    }
}

plugins - webpack自带插件

插件配置是webpack中的难点, 下面将列出一些常用的插件配置方法

NormalModuleReplacementPlugin

用newResource 替换用resourceRegExp 匹配到的资源。
如果newResource 用的相对路径,则路径 相对于以前的资源。
如果newResource 用的是函数,预期重写该函数提供的对象的“request”属性。
使用方法: new webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource)

{
    plugins: [
        new webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource)
    ]
}

ContextReplacementPlugin

如果资源(或者目录)匹配resourceRegExp ,这个插件替换默认资源,递归标记,或者替换掉由各自分析 newContentResource 、newContentRecursive 、newContentRegExp 得到的正则。
如果 newContentResource 是相对路径,则其路径相对于之前的资源。
如果用的是函数,预期重写该函数提供的对象的“request”属性。

{
    plugins: [
        new webpack.ContextReplacementPlugin(
            resourceRegExp,
            [newContentResource],
            [newContentRecursive],
            [newContentRegExp]
        )
    ]
}

IgnorePlugin

不为所提供的正则表达式匹配到的模块生成模块。

requestRegExp 匹配请求的正则。
contextRegExp (可选项)匹配上下文(目录)的正则。

{
    plugins: [
        new webpack.IgnorePlugin(requestRegExp, [contextRegExp])
    ]
}

PrefetchPlugin

为一个正常模块的请求。这个请求会在打包之前发生。这样会提高效率。

context 一个目录的绝对路径
request 一个正常的模块的请求字符串

{
    plugins: [
        new webpack.PrefetchPlugin([context], request)
    ]
}

ResolverPlugin

应用一个插件(或者一个插件组)到一个或者多个resolvers (types指定的)
plugins 一个插件(或者一个插件组),它会被用到resolver(s)
types 一个resolver的类型或者一个resolver的类型数组。(默认["normal"],resolver types: normal, context, loader)

{
    plugins: [
        new webpack.ResolverPlugin([
            new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
        ], ["normal", "loader"])
    ]
}

EnvironmentPlugin

这个插件将允许您通过process.env引用环境变量

{
    plugins: [
        new webpack.EnvironmentPlugin([
            "NODE_ENV"
        ])
    ]
}

在代码中: var env = process.env.NODE_ENV

BannerPlugin

给每一个chunk顶部加一个banner
banner 一个字符串,它将被包装在一个注释里
options.raw 如果为true,banner不会被包在注释里
options.entryOnly 如果为true,banner只会被添加到入口chunk

{
    plugins: [
        new webpack.BannerPlugin('这里是打包文件头部注释!', {
            raw: false,
            entryOnly: false
        })
    ]
}

DedupePlugin (推荐使用)

搜索同样或者相似的文件,在output中去重。它会加重入口文件的开销,但会有效地缩小文件的大小。
这不会改变在所有模块的语义。别指望来解决多模块实例。在去重后,它们不会成为一个实例。
注意:在watch模式下不要用它,只有在生产环境中再去用

{
    plugins: [
        new webpack.optimize.DedupePlugin()
    ]
}

LimitChunkCountPlugin

限制 chunck数量。chunck会被合并只到合适。
options.maxChunks 块的最大数量
ptions.chunkOverhead 以字节为单位的每个块的额外开销
options.entryChunkMultiplicator 入口文件的一个系数(默认10)

{
    plugins: [
        new webpack.optimize.LimitChunkCountPlugin({
            maxChunks: 5,
            chunkOverhead: 1024,
            entryChunkMultiplicator: 10
        })
    ]
}

MinChunkSizePlugin

合并低于这个最小尺寸的小块, 近似大小。
options.minChunkSize: 小于这个数字的块将被合并

{
    plugins: [
        new webpack.optimize.MinChunkSizePlugin({
            minChunkSize: 5
        })
    ]
}

OccurrenceOrderPlugin (推荐使用)

给module和 chunk分配id。经常使用的id更低(更短)。这让ids变得可预测的,也可以减小文件体积。建议使用。

{
    plugins: [
        new webpack.optimize.OccurrenceOrderPlugin()
    ]
}

UglifyJsPlugin (推荐使用)

最小化所有JavaScript输出块。 loader切换到轻便模式。你可以传递一个对象,包含UglifyJS选项。你可以传递一个包含UglifyJS选项的对象

{
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        })
    ]
}

其他选项:
sourceMap : 插件使用SourceMaps 标出出错模块的位置。会减慢编译速度。(默认true)
test, include, exclude :正则或者正则数组。用来筛选处理过的文件。(默认:test: /.js($|\?)/i)

重整名称配置
关于重整的变量名的具体配置。默认情况 mangle选项是on.但是你可以传递一个列表自己配置插件

{
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            mangle: {
                except: ['$super', '$', 'exports', 'require']
            }
        })
    ]
}

用了这个配置,webpack不会损坏 "$super", "$", "exports" 或者 "require"这些关键词

CommonsChunkPlugin (推荐使用)

  • options.name 或 options.names (string 或[string]): commons chunk的名称。
    传入一个已经存在的块名,这个块儿会被选中。
    如果传递一个字符串数组,这等于多次调用插件为每个块名称。
    如果省略并且设置了options.async 或 options.children 所有chunk都会被选中。否则options.name会被作为一个块名。
  • options.filename(string) : 公共块的文件名模板。
    可以像output.filename一样包含同一占位符 。
    如果省略,源文件名不会变(一般是output.filename或者output.chunkFilename)。
  • options.minChunks(number|Infinity|function(module, count) -> boolean): chunk数量的最低值。
    这些chunk在它被移到 公共块前需要包含一个模块。
    这个值必须大于2小于chunk总数。
  • options.chunks (string[]) : 通过chunk名选择源chunk。
    这个块必须是公共块的子块。如果忽略,所有 入口块都会被选中。
  • options.children(boolean): 如果为真,所有公共chunk的子块都会被选中。
  • options.async(boolean|string): 如果为真,一个新的异步chunk将作为options.name的子块儿和options.chunks的兄弟块儿被创建。它与options.chunks并行加载。
  • options.minSize (number): 在公共块创建前所有公共块的最小值
1. 入口文件的 Common chunk

生成一个额外的包含入口点共享的通用模块的chunk

{
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: "commons",
            // filename: "commons.js",
            // minChunks: 3,
            chunks: ["pageA", "pageB"]
        })
    ]
}

注意: 你必须在入口点之前加载这个chunk

2. 显式的依赖 chunk

把你的代码折分为依赖和应用

{
    entry: {
        vendor: ["jquery", "other-lib"],
        app: "./entry"
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: "vendor",
            filename: "vendor.js",
            minChunks: Infinity
        })
    ]
}

注意: 结合长期的缓存,你需要用chunk-manifest-webpack-plugin这个插件来阻止vendor chunk的变化。你还应该使用records来确保稳定的模块id

3. 把公共模块移动到父chunk

用了代码分割,子模块可以用到公共模块。你可以把公共模块移动到父模块中

{
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            children: true
        })
    ]
}
4. 提取异步公共块儿
{
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            children: true,
            async: true
        })
    ]
}

AggressiveMergingPlugin

一个更具侵略性的块合并策略的插件,即使是相似的块也会被合并,如果总尺寸减小到足够。作为一个在这些块中不常见的选项模块,可以将块树移动到父模块
options.minsizereduce: 默认值为: 1.5, 这意味着尺寸需要减少50%的块才会被合并
options.moveToParents
options.entryChunkMultiplicator

{
    plugins: [
        new webpack.optimize.AggressiveMergingPlugin({
            chiminsizereduceldren: 1.5
        })
    ]
}

HotModuleReplacementPlugin (推荐使用)

启用热模块替换

{
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]
}

NoErrorsPlugin

{
  plugins: [
    new webpack.NoErrorsPlugin()
  ]
}

DefinePlugin

{
    plugins: [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': '"development"',
            PRODUCTION: JSON.stringify(true),
            VERSION: JSON.stringify("5fa3b9"),
            BROWSER_SUPPORTS_HTML5: true,
            TWO: "1+1",
            "typeof window": JSON.stringify("object")
        })
    ]
}

DllPlugin 和 DllReferencePlugin

另讲

plugins - 第三方插件

FaviconsWebpackPlugin

https://github.com/jantimon/favicons-webpack-plugin

const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
{
  plugins: [
    new FaviconsWebpackPlugin('my-logo.png')
  ]
}

WebpackBrowserPlugin

https://github.com/1337programming/webpack-browser-plugin

const WebpackBrowserPlugin = require('webpack-browser-plugin');
{
  plugins: [
    new WebpackBrowserPlugin();
  ]
}

WebpackShellPlugin

https://github.com/1337programming/webpack-shell-plugin

const WebpackShellPlugin = require('webpack-shell-plugin');
{
  plugins: [
    new WebpackShellPlugin({
      onBuildStart: ['echo "Starting"'],
      onBuildEnd: ['node openBrowser.js']
    })
  ]
}

BellOnBundlerErrorPlugin

https://github.com/senotrusov/bell-on-bundler-error-plugin

const BellOnBundlerErrorPlugin = require('bell-on-bundler-error-plugin')
{
    plugins: [
        new BellOnBundlerErrorPlugin()
    ]
}

HtmlWebpackPlugin (推荐使用)

将打包好的的模块注入html文件
https://github.com/ampedandwired/html-webpack-plugin

const BellOnBundlerErrorPlugin = require('bell-on-bundler-error-plugin')
{
    plugins: [
        new HtmlWebpackPlugin({
            inject: true,
            chunks: ['commons', 'app'],
            filename: 'index.html',
            template: 'index.html',
            favicon: faviconPath,
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeRedundantAttributes: true
            }
        })
    ]
}

RewirePlugin

https://github.com/jhnns/rewire-webpack

var RewirePlugin = require("rewire-webpack")
{
    plugins: [
        new RewirePlugin()
    ]
}

ExtractTextPlugin (推荐使用)

合并CSS文件
https://github.com/webpack/extract-text-webpack-plugin

var ExtractTextPlugin = require('extract-text-webpack-plugin')
{
    module: {
        loaders: [{
            test: /\.css$/,
            loader: ExtractTextPlugin.extract(['css?-autoprefixer', 'postcss'])
        }]
    },
    plugins: [
        new ExtractTextPlugin('[name].[contenthash].css')
    ]
}
发表评论
abcd498936590
有一些内容很模糊说的,本来搜到这里就想看的全面些,结果……网上的教程实在是太墨模糊了,具体使用场景chunk-manifest-webpack-plugin这个怎么玩???本来有很多webpack方面的疑问想问,迫于无奈,很多群里都没人问津
%E9%85%B8%E9%85%B8%E7%9A%84
很全,很好!