美文网首页
webpack配置说明

webpack配置说明

作者: 简书小呆 | 来源:发表于2019-07-02 11:45 被阅读0次

    webpack 4

    webpack 的运行说明

    webpack 的运行有多种

      1. 通过命令行
     webpack  (默认weback 都是当前目录下的查找webpack.config.js 和 webpack-dev-server 一样)
    // 等价于
     webpack --config ./webpack.config.js 
    
      1. 通过node Api的weback函数启动
      const config = require('./webpack.config.js');
      const webpack = require('webpack');
      const compiler = webpack(config,(err, stats) => {
      if (err || stats.hasErrors()) {
        console.error(err);
        return;
      }
      console.log(stats);
    })
    
      1. 通过node Api Compiler 实例的.run()函数启动
     const config = require('./webpack.config.js');
     const webpack = require("webpack");
    
      const compiler = webpack({
      // 配置对象
      });
      compiler.run((err, stats) => {
      });
    
      1. 通过node Api Compiler 实例的.watch( watchOptions, handler )函数启动
     const config = require('./webpack.config.js');
     const webpack = require("webpack");
    
      const compiler = webpack({
      // 配置对象
      });
    // 运行并开启监听模式
      const watching = compiler.watch({
       // watchOptions 示例
        aggregateTimeout: 300,
        poll: undefined
      },(err, stats) => {
    
      });
    

    webpack通过node Api 访问webpack 钩子 ( 根据不同的钩子 使用同步方式触及 compile 钩子 还是 异步触发compile 钩子 )

        // 监听模式下才可以触发这个钩子
        compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
          hotMiddleware.publish({ action: 'compiling' })
          done()
        })
    

    webpack config中的常用配置说明

    const TerserPlugin = require('terser-webpack-plugin');
    const webpack = require('webpack');
    
    
    let  config = { 
        // 基础目录,绝对路径,用于从配置中解析入口起点(entry point)和 loader
        // 类型: string
        // 默认: process.cwd() 当前目录 
        context: __dirname,
        // 入口
        // 类型: string | [string] | object { <key>: string | [string] } | (function: () => string | [string] | object { <key>: string | [string] })
        entry: { // 对象语法可以 跟
            app: './src/app.js',
            vendors: './src/vendors.js' 
        }, 
        // 出口
        output:{
            chunkFilename:'bundle.[id].[name].[hash].[chunkhash].js',
            filename: 'bundle.[id].[name].[hash].[chunkhash].js', 
            path: path.join(__dirname, '../dist'), // 对应一个绝对路径,此路径是你希望一次性打包的目录。
            publicPath :'', // 静态文件的
            crossOriginLoading: false | "anonymous" | "use-credentials", 
            devtoolLineToLine: false | {test, include, exclude} | true, 
            library: 'ajax', // 导出的变量名 或者 模块名 
            libraryTarget: "var" | "this" | "commonjs" | "commonjs2" | "amd" | "umd",
            libraryExport: 'default' ,
            auxiliaryComment:'我是注释!', // 在和 output.library 和 output.libraryTarget 一起使用时,此选项允许用户向导出容器(export wrapper)中插入注释。要为 libraryTarget 每种类型都插入相同的注释,将 auxiliaryComment 设置为一个字符串:
        
        },
        // 模块 就是俗称的loader
        module:{
            noParse: (content) => /jquery|lodash/.test(content),
            rules:[
                {
                    test: /\.js$/,
                    include: [ path.join(__dirname, '../src') ],
                    exclude: /node_modules/,
                    // loader:'css-loader', Rule.loader 是 Rule.use: [ { loader } ] 的简写
                    // Rule.options 和 Rule.query 是 Rule.use: [ { options } ] 的简写
                    // resource: {
                        // test: /\.js$/,
                        // include: [ path.join(__dirname, '../src/renderer') ],
                        // exclude: /node_modules/,
                    // }
                    // import Foo from './foo.css?inline'
                    // resourceQuery: /inline/,
                    parser:{ // 语法分析器
                        amd: false, // 禁用 AMD
                        commonjs: false, // 禁用 CommonJS
                        system: false, // 禁用 SystemJS
                        harmony: false, // 禁用 ES2015 Harmony import/export
                        requireInclude: false, // 禁用 require.include
                        requireEnsure: false, // 禁用 require.ensure
                        requireContext: false, // 禁用 require.context
                        browserify: false, // 禁用特殊处理的 browserify bundle
                        requireJs: false, // 禁用 requirejs.*
                        node: false, // 禁用 __dirname, __filename, module, require.extensions, require.main 等。
                        node: {} // 在模块级别(module level)上重新配置 node 层(layer)
                    },
                    // Rule.loader 是 Rule.use: [ { loader } ] 的简写
                    use: [
                        {             
                          loader: 'babel-loader',
                          options: { 
                            
                          },
                          
                        }
                    ],
                
                }
            ]
        },
        // 路径目录
        resolve:{
            // 创建 import 或 require 的别名
            alias:{
                Utilities: path.join(__dirname, 'src/utilities/'),
                Templates: path.join(__dirname, 'src/templates/') 
            },
            aliasFields: ['browser'],  // 'module', 'main' 这个 browser 必须在被引用的模块的package.json 配置才能生产,并且只对这个模块生效。
            extensions: ['.wasm', '.mjs', '.js', '.json'],
    
            descriptionFiles:['package.json'], // 用于描述的 JSON 文件
            mainFields: ['browser', 'module', 'main'], // 当 target 属性设置为 webworker, web 或者没有指定,默认值为:['browser', 'module', 'main'] 对于其他任意的 target(包括 node),默认值为:  ['module', 'main'] 
            mainFiles: ['index'], // 解析目录时要使用的文件名。
            modules: ['node_modules'], // 告诉 webpack 解析模块时应该搜索的目录。
            enforceExtension: false,  // 如果配置为  true  所有导入语句都必须要带文件后缀, 例如开启前  import './foo'  能正常工作,开启后就必须写成  import './foo.js' 
            enforceModuleExtension: false, // nforceModuleExtension  和  enforceExtension  作用类似,但  enforceModuleExtension  只对  node_modules  下的模块生效。  enforceModuleExtension  通常搭配  enforceExtension  使用,在  enforceExtension:true  时,因为安装的第三方模块中大多数导入语句没带文件后缀, 所以这时通过配置  enforceModuleExtension:false  来兼容第三方模块。
    
            unsafeCache: true, // unsafeCache: /src\/utilities/ regex | array | boolean 启用,会主动缓存模块,但并不安全。传递 true 将缓存一切。默认:unsafeCache: true
            plugins:[
                new DirectoryNamedWebpackPlugin() 
            ]
        },
         // loader的路径目录解析
        resolveLoader:{ // 这组选项与上面的 resolve 对象的属性集合相同,但仅用于解析 webpack 的 loader 包。默认:
            modules: ['node_modules'],
            extensions: ['.js', '.json'],
            mainFields: ['loader', 'main'],
    
            moduleExtensions : ['-loader'], // 解析 loader 时,用到扩展名(extensions)/后缀(suffixes)。从 webpack 2 开始,我们 强烈建议 使用全名,例如 example-loader,以尽可能清晰。然而,如果你确实想省略 -loader,也就是说只使用 example,则可以使用此选项来实现:
        },
        // 模式
        mode:'production', // 可能的值有:none, development 或 production(默认)。提供 mode 配置选项,告知 webpack 使用相应环境的内置优化。
        // 优化
        optimization:{
            minimize: false, // 压缩
            minimizer:[ // 允许你通过提供一个或多个定制过的 TerserPlugin 实例,覆盖默认压缩工具(minimizer)。
                new TerserPlugin({
                    cache: true,
                    parallel: true,
                    sourceMap: true, // Must be set to true if using source-maps in production
                    terserOptions: {
                      // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
                    }
                  }),
                //   Or, as function:
                //   (compiler) => {
                //     const TerserPlugin = require('terser-webpack-plugin');
                //     new TerserPlugin({ /* your config */ }).apply(compiler);
                //   }
            ],
            splitChunks:{
    
                // 模块组 缓存组概念
                chunks: 'async', // 默认只作用于异步模块,‘all’时对所有模块生效, ‘initial’对同步模块有效
                minSize: 30000,  // 新产出的vendor-chunk的大小要大于30kb
                minChunks: 2,    //共同引用超过大于等于2次就可以分割成公共模块
                maxAsyncRequsets: 5, // 并行请求vendor-chunk的数量不能超出5个
                maxInitialRequests: 3, // 对于entry-chunk,并行加载的vendor-chunk不能超出3个
                name:true, //神奇的true值将会自动根据切割之前的代码块和缓存组键值(key)自动分配命名,否则就需要传入一个String或者function.
                            // 命名与入口名称相同时,入口将会被移除.
                automaticNameDelimiter:'~',
    
                cacheGroups:{ // 缓存组默认继承splitChunks的配置项,但是test,priority和reuseExistingChunk只能在缓存组中被配置.
                    commons: {
                        name: "commons",
                        chunks: "all", 
                        minChunks: 2,
                        
                        priority: 0,
                        minSize:0,
                    },
                    vendor: { 
                        name: 'vendor',
                        test: /[\\/]node_modules[\\/]/,
                        chunks: 'all', 
                        priority: 10 
                    },
                    default:{ // false 来禁用 默认缓存组,
                
    
                    } , 
    
                }, //end cacheGroups
    
            }, // end splitChunks
    
            // runtimeChunk: true,// 或 "multiple" 以下的别名
            // runtimeChunk: {
            //     name: entrypoint => `runtime~${entrypoint.name}`
            // },
            // runtimeChunk: 'single', // 以下的别名 
            runtimeChunk: { 
                name: 'runtime'
            },
            noEmitOnErrors : true, // 在编译出错时,使用 optimization.noEmitOnErrors 来跳过生成阶段(emitting phase)。   
            nodeEnv: "production", // 告知 webpack 将 process.env.NODE_ENV 设置为一个给定字符串。如果 optimization.nodeEnv 不是 false,则会使用 DefinePlugin,optimization.nodeEnv 默认值取决于 mode,如果为 falsy 值,则会回退到 "production"。
            //parent chunk中解决了的chunk会被删除
            removeAvailableModules:true,
            //删除空的chunks
            removeEmptyChunks:true,
            //合并重复的chunk
            mergeDuplicateChunks:true,
    
    
    
    
    
        }, //end optimization
        // 插件
        plugins: [
            // mode : 'development'时的插件添加模式后可省略 
            new webpack.NamedModulesPlugin(), // 在热加载时直接返回更新文件名,而不是文件的id。
            new webpack.NamedChunksPlugin(), 
            new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), 
    
            // mode : 'production'时的插件添加模式后可省略 
            new TerserPlugin({ test: /\.js(\?.*)?$/i,}), // js压缩优化 用terser-webpack-plugin替换掉uglifyjs-webpack-plugin解决uglifyjs不支持es6语法问题
            // new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
            new webpack.optimize.ModuleConcatenationPlugin(), // 将所有模块的作用域连接到一个闭包中,从而使代码在浏览器中具有更快的执行时间。
            new webpack.NoEmitOnErrorsPlugin(), //  在编译出错时,使用 optimization.noEmitOnErrors 来跳过生成阶段(emitting phase)。优化中有
    
    
            new CopyWebpackPlugin(),         // 将单个文件或整个目录复制到构建目录
            new webpack.BannerPlugin(options), // 在每个生成的块的顶部添加横幅。
            new HtmlWebpackPlugin(),         // 简单创建 HTML 文件,用于服务器访问
            new webpack.HotModuleReplacementPlugin(options),// 启用模块热替换(Enable Hot Module Replacement - HMR)
            new ExtractTextWebpackPlugin(options),  // 从 bundle 中提取文本(CSS)到单独的文件
            new OptimizeCSSPlugin(options), // 压缩提取的CSS。我们使用这个插件是为了可以消除来自不同组件的重复CSS。
            // new webpack.optimize.CommonsChunkPlugin(options), // 从webpack 4中删除了  提取 chunks 之间共享的通用模块
            // new UglifyjsWebpackPlugin(),     // 优化js的插件可以使用在optimization.minimizer中 可以控制项目中 UglifyJS 的版本 
    
    
            new webpack.optimize.AggressiveSplittingPlugin(options), // 将原来的 chunk 分成更小的 chunk
            new webpack.optimize.LimitChunkCountPlugin(options),     // 设置 chunk 的最小/最大限制,以微调和控制 chunk  当你在编写代码时,可能已经添加了许多代码分离点(code split point)来实现按需加载(load stuff on demand)。在编译完之后,你可能会注意到有一些很小的 chunk - 这产生了大量 HTTP 请求开销。LimitChunkCountPlugin 插件可以通过合并的方式,后处理你的 chunk,以减少请求数。
            new webpack.optimize.MinChunkSizePlugin(options),        // 确保 chunk 大小超过指定限制
            
            new webpack.AutomaticPrefetchPlugin(), // AutomaticPrefetchPlugin在观察更改的同时,提前发现以前编译的所有模块,试图改进增量构建时间。与预先发现单个模块的PrefetchPlugin相比。
            new webpack.ContextReplacementPlugin(),  // 重写 require 表达式的推断上下文
            new webpack.DllPlugin(options),                 // 为了极大减少构建时间,进行分离打包
            new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']),   // DefinePlugin 中 process.env 键的简写方式。
            new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),      // 从 bundle 中排除某些模块
            new webpack.LoaderOptionsPlugin(options),       // 用于从 webpack 1 迁移到 webpack 2
            new webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource),// 替换与正则表达式匹配的资源
            new webpack.ProvidePlugin(options),             // 不必通过 import/require 使用模块
            new webpack.SourceMapDevToolPlugin(options),    // 对 source map 进行更细粒度的控制
            new webpack.EvalSourceMapDevToolPlugin(options),// 对 eval source map 进行更细粒度的控制
            
            new CompressionWebpackPlugin(),  // 可以压缩成gzip 预先准备的资源压缩版本,使用 Content-Encoding 提供访问服务
            new ZopfliWebpackPlugin(options),       // 通过 node-zopfli 将资源预先压缩的版本 压缩
            new BabelMinifyWebpackPlugin(minifyOpts, pluginOpts),  // 使用 babel-minify进行压缩
            new I18nWebpackPlugin(languageConfig, optionsObj),         // 为 bundle 增加国际化支持
            new NpmInstallWebpackPlugin(options),   // 在开发时自动安装缺少的依赖
            
    
        ],
        // devtool 你可以直接使用 SourceMapDevToolPlugin/EvalSourceMapDevToolPlugin 来替代使用 devtool 选项,切勿同时使用 devtool 选项和 SourceMapDevToolPlugin/EvalSourceMapDevToolPlugin 插件。
        // 类型: string false
        devtool:'cheap-eval-source-map',
        // 开发中  影响 webpack-dev-server(简写为:dev-server) 行为的选项。
        devServer: {
            contentBase: path.join(__dirname, 'dist'), // 告诉服务器从哪个目录中提供内容。只有在你想要提供静态文件时才需要。 推荐使用一个绝对路径。
            compress: true, // 一切服务都启用 gzip 压缩:
            port: 9000,  // 端口号
            after: function(app, server) { // 在服务内部的所有其他中间件之后, 提供执行自定义中间件的功能。
            },
            before: function(app, server) { // 在服务内部的所有其他中间件之前, 提供执行自定义中间件的功能。 这可以用来配置自定义处理程序,
                app.get('/some/path', function(req, res) {
                    res.json({ custom: 'response' });
                });
            },
            allowedHosts :[ 'host.com', 'host2.com' ], // 此选项允许你添加白名单服务,允许一些开发服务器访问。
            color: true, // 启用/禁用控制台的彩色输出。
            lazy: true,  // lazy mode(惰性模式) 
            filename: 'bundle.js', // 在 lazy mode(惰性模式) 中,只有在请求 /bundle.js 时候,才会编译 bundle。
            headers: { // 在所有响应中添加首部内容:
                'X-Custom-Foo': 'bar'
            },
            historyApiFallback: true, // 使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html。devServer.historyApiFallback 默认禁用。通过传入以下启用:
            host: '0.0.0.0', // 指定使用一个 host。默认是 localhost。如果你希望服务器外部可访问,指定如下:
            hot: true, // 启用 webpack 的 模块热替换 功能:注意,必须有 webpack.HotModuleReplacementPlugin 才能完全启用 HMR。如果 webpack 或 webpack-dev-server 是通过 --hot 选项启动的,那么这个插件会被自动添加,所以你可能不需要把它添加到 webpack.config.js 中。关于更多信息,请查看 HMR 概念 页面。
            hotOnly: true, // 启用热模块替换(请参阅devserver.hot),而不将页面刷新作为生成失败时的回退。
            // boolean object
            // https: true,  //  默认情况下,dev-server 通过 HTTP 提供服务。也可以选择带有 HTTPS 的 HTTP/2 提供服务:
            https: {
                key: fs.readFileSync('/path/to/server.key'),
                cert: fs.readFileSync('/path/to/server.crt'),
                ca: fs.readFileSync('/path/to/ca.pem'),
            },
            index: 'index.html', // 被作为索引文件的文件名。
            inline: true,  // 推荐使用 模块热替换 的内联模式,
            noInfo: true,  // 告诉 dev-server 隐藏 webpack bundle 信息之类的消息。devServer.noInfo 默认禁用。
            // boolean string
            open:'Google Chrome', // 告诉 dev-server 在 server 启动后打开浏览器。默认禁用。
            openPage: '/different/page', // 指定打开浏览器时的导航页面。
            // boolean object: { boolean errors, boolean warnings }
            overlay: { // 如果想要显示警告和错误:
                warnings: true,
                errors: true
            }, 
            // object [object, function]
            // proxy: { // 请求到 /api/users 现在会被代理到请求 http://localhost:3000/api/users。
            //     '/api': 'http://localhost:3000'
            // },
            // '/api': {  // 如果你不想始终传递 /api ,则需要重写路径:
            //     target: 'http://localhost:3000',
            //     pathRewrite: {'^/api' : ''}
            // },
            // '/api': { // 默认情况下,不接受运行在 HTTPS 上,且使用了无效证书的后端服务器。如果你想要接受,修改配置如下:
            //     target: 'https://other-server.example.com',
            //     secure: false
            // },
            // '/api': { // 有时你不想代理所有的请求。可以基于一个函数的返回值绕过代理。
            //     target: 'http://localhost:3000',
            //     bypass: function(req, res, proxyOptions) {
            //       if (req.headers.accept.indexOf('html') !== -1) {
            //         console.log('Skipping proxy for browser request.');
            //         return '/index.html';
            //       }
            //     }
            // },
            proxy: [{ //如果你想要代理多个路径特定到同一个 target 下,你可以使用由一个或多个「具有 context 属性的对象」构成的数组:
                context: ['/auth', '/api'],
                target: 'http://localhost:3000',
            }],
            // publicPath: '/assets/', // 将 bundle 放在指定目录下:现在可以通过 http://localhost:8080/assets/bundle.js 访问 bundle。
            publicPath: 'http://localhost:8080/assets/',  // 也可以使用一个完整的 URL。这是 模块热替换 所必需的。
            quiet: true, // 启用 devServer.quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。 
            socket: 'socket', // 用于监听的 Unix socket(而不是 host)。
            staticOptions: { // 这只有在使用 devServer.contentBase 是一个 string 时才有效。 可以用于对 contentBase 路径下提供的静态文件,进行高级选项配置。有关可能的选项,请查看 Express文档。
                redirect: false
            },
            // string: 'none' | 'errors-only' | 'minimal' | 'normal' | 'verbose' object
            stats: 'errors-only', 
            useLocalIp: true, // 此选项允许浏览器使用本地 IP 打开。
            watchContentBase: true, // 告知 dev-server,serve(服务) devServer.contentBase 选项下的文件。开启此选项后,在文件修改之后,会触发一次完整的页面重载。
            watchOptions: { // webpack 使用文件系统(file system)获取文件改动的通知。在某些情况下,不会正常工作。例如,当使用 Network File System (NFS) 时。Vagrant 也有很多问题。在这些情况下,请使用轮询: 如果这对文件系统来说太重了的话,你可以修改间隔时间(以毫秒为单位),将其设置为一个整数。
                poll: true
            },
            // boolean: false function (filePath)
            writeToDisk: (filePath) => {
                return /superman\.css$/.test(filePath);
            },
    
    
        },
        // 构建目标 string | function (compiler) 
        // target:'web', // async-node electron-main electron-renderer node node-webkit web  webworker
        target: (compiler) => {
            compiler.apply(
              new webpack.JsonpTemplatePlugin(options.output),
              new webpack.LoaderTargetPlugin('web')
            );
        },
        // boolean: false  是否开启观察模式
        watch:true,
        watchOptions: {
            aggregateTimeout: 300, //当第一个文件更改,会在重新构建前增加延迟。这个选项允许 webpack 将这段时间内进行的任何其他更改都聚合到一次重新构建里。以毫秒为单位:
            poll: 1000, // 每秒检查一次变动
            // ignored: /node_modules/, //对于某些系统,监听大量文件系统会导致大量的 CPU 或内存占用。这个选项可以排除一些巨大的文件夹,例如 node_modules:
            ignored: ['files/**/*.js', 'node_modules'],
    
        },
        // string object function regex 外部扩展不被webpack打包的模块
        externals : {
            lodash : {
                commonjs: 'lodash',
                amd: 'lodash',
                root: '_' // 指向全局变量
            }
        },
        // 这些选项可以配置是否 polyfill 或 mock 某些 Node.js 全局变量和模块。这可以使最初为 Node.js 环境编写的代码,在其他环境(如浏览器)中运行。
        node: {
            console: false,
            global: true,
            process: true,
            __filename: 'mock',
            __dirname: 'mock',
            Buffer: true,
            setImmediate: true  
            // 更多选项,请查看“其他 Node.js 核心库”。
        },
        // 性能
        performance:{
            hints: false, // false | "error" | "warning"
            maxEntrypointSize: 400000, // 入口起点表示针对指定的入口,对于所有资源,要充分利用初始加载时(initial load time)期间。此选项根据入口起点的最大体积,控制 webpack 何时生成性能提示。默认值是:250000 (bytes)。
            maxAssetSize: 100000, // 资源(asset)是从 webpack 生成的任何文件。此选项根据单个资源体积,控制 webpack 何时生成性能提示。默认值是:250000 (bytes)。
            assetFilter: function(assetFilename) { //此属性允许 webpack 控制用于计算性能提示的文件
                return assetFilename.endsWith('.js');
            },
            // 统计信息(stats)  如果你不希望使用 quiet 或 noInfo 这样的不显示信息,而是又不想得到全部的信息,只是想要获取某部分 bundle 的信息,使用 stats 选项是比较好的折衷方式。
            // 对于 webpack-dev-server,这个属性要放在 devServer 对象里。在使用 Node.js API 时,此选项无效。 
            stats : 'errors-only',
    
    
    
        }
    
    }
    

    相关文章

      网友评论

          本文标题:webpack配置说明

          本文链接:https://www.haomeiwen.com/subject/gbqrcctx.html