webpack-笔记-1

143 阅读4分钟

webpack-笔记-1

webpack官方文档是学习webpack的最佳途径之一。以下是基于官方文档罗列的各项做的自我整理。

版本:webpack-4+

webpack.config.js

webpack的配置文件一般是javaScript文件,webpack.config.js(但也支持其他配置语言)。该文件内会导出一个webpack配置对象。

在配置中你可以:

  • 通过require(...)引入其他文件
  • 通过require(...)使用npm下载的工具函数
  • 使用JS控制流、表达式(with语句、onerror事件、?:操作符)
  • value使用常量或变量赋值
  • 编写&执行函数,生成部分配置

[eg.]webpack.config.js

const path = require('path');

module.exports = {
    mode: 'development',
    entry: './index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
    },
};

[eg.]webpack.config.ts

使用TypeScript来编写webpack配置。

1.安装依赖

npm install typescript ts-node @types/node @types/webpack -D
# 版本低于 v4.7.0的 webpack-dev-server,还需安装如下依赖
npm install @types/webpack-dev-server -D

2.配置文件

import * as path from 'path';
import * as webpack from 'webpack';
// 使用devServer时,保险起见
import 'webpack-dev-server'

const config: webpack.Configuration = {
    mode: 'production',
    entry: './index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
    },
};

export default config;

其他设置及其他配置语言参考:

webpack.docschina.org/configurati…

配置内容(选项)

基本框架:

const path = require('path');

module.exports = {
    mode: String,
    entry: String|object|array,
    output: {...},
    module: {...},
    resolve: {...},
    performance: {...},
    devtool: enum,
    context: String,
    target: enum,
    externals: ...,
    externalsType: ...,
    externalsPresets: ...,
    ignoreWarnings: ...,
    stats: ...,
    devServer: {...},
    experiments: {...},
    optimization: {...},

}

[mode]

常用:

module.exports = {
    mode: 'development',//'none' | 'development' | 'production'
}

从CLI参数中传递

webpack --mode=development

含义

  • development:调试模式
  • production:生产模式
  • 默认:production

根据该变量的动态配置:

var config = {
    entry: './app.js',
    // ...
};

module.exports = (env, argv) => {
    if(argv.mode === 'development') {
        config.devtool = 'source-map'
    }
}

[entry]

打包的一个或多个入口起点。动态加载的模块不是入口起点。一般来说:单页应用一个入口起点;多页应用多个入口起点。

module.exports = {
    entry: {
        home: './home.js',
        about: './about.js',
        contact: './contact.js',
    }    
}
// 此时output也应为多个

常用

字符型
module.exports = {
    // 入口
    entry: './src/index.js',
    // 出口
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist)
    }
}
数组型

多个入口文件会打包成一个

module.exports = {
    // 入口
    entry: ["./src/index.js","./src/a.js"],
    // 出口
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist)
    }
}

对象型

此时通过test1这样的k-v对,指定了多文件打包:output中的[name]来产生多文件输出

module.exports = {
    // 入口
    entry: {
        test1: ["./src/index.js","./src/a.js"],
        test2: "./src/b.js"
    },
    // 出口
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist)
    }
}

其他属性

这些属性分布在

module.exports = {
    entry: {
        filename: {
            // 分布在这里,导入要用import
            import: './src/a.js'
        }
    }
}
import

用于在入口处加载更多配置属性时,指明入口文件

dependOn-依赖文件

当前入口所依赖的入口,必须在该入口被加载前加载

module.exports = {
    entry: {
        a: 'depending.js',// 所依赖的入口
        b: {
            // 提前加载
            dependOn: 'a',
            //当前入口
            import: './src/app.js',
        }
    }
}

效果:

<head>
    <script src="depending.js"></script>
</head>
<body>
    <script src='./src/app.js'></script>
</body>

注意:

  • 不要与runtime在同一个入口(b:{ dependOn:xxx,runtime:yyy,...})处共用
  • 不要循环引用
runtime-运行时代码

编译时,Webpack 会根据业务代码决定输出那些支撑特性的运行时代码,为了避免这部分的代码在多个入口中被重复打包,webpack5提供了entry.runtime

module.exports = {
    entry: {
        a: {
            import: './src/index.js',
            // 这里的String实际上也将产生一个输出文件,避免与入口同名,以免造成文件覆盖
            runtime: 'my-runtime',
        },
        b: {
            import: './src/a.js',
            runtime: 'my-runtime'
        }
    }
}

注意

  • 避免与入口同名,以免造成文件覆盖

[output]

针对输出文件的配置,与[entry]联合使用。

常用

单入口文件
module.exports = {
    ...
    output:{
        filename: 'bundle.js',
    }
}
多入口文件
module.exports = {
    ...
    output: {
        filename: '[name].js',
        path: __dirname + '/dist'
    }
}

属性

filename

决定输出bundle的名称

对于单个入口,filename可以是一个静态名称

module.exports = {
    // ...
    output: {
        filename: 'bundle.js'
    }
}

对于多入口,可以使用以下方式替换,动态指定bundle名称

[name]:使用入口名称

module.exports = {
    output: {
        filename: '[name].bundle.js',
    }
}

[id]:使用内部chunk id

module.exports = {
    output: {
        filename: '[id].bundle.js',
    }
}

[contenthash]:由生成内容产生的hash

module.exports = {
    output: {
        filename: '[contenthash].bundle.js'
    }
}

以上内容可以联合使用

function:使用函数返回filename

module.exports = {
    output: {
        filename: (pathData) => {
            return pathData.chunk.name === 'main'?'[name].js':'[name]/[name].js';
        }
    }
}
path

对应一个绝对路径,用于存放输出资源

clean

打包时如何处理输出目录中的原有文件

  • 生成文件前,清空output
module.exports = {
    output: {
        clean:true
    }
}
  • 打印而不是删除应该移除的静态资源
module.exports = {
    output: {
        clean: {
            dry:true
        }
    }
}
  • 保留'ignored/dir' 下的静态资源

    module.exports = {
        output: {
            clean:{
                keep: /ignored/dir//,
            }
        }
    }
    
chunkFilename-懒加载\按需加载

这是一个与懒加载\按需加载相关的属性。webpack将那些非初始加载的模块放到单独的chunk中去。这些chunk 文件的名称与此属性相关。webpack通过import来判断是否是按需加载的内容:

btn.addEventListener('click',()=>{
    import('./a').then(()=> {
        console.log('加载a')
    })
})
module.exports = {
    output: {
        filename: 'bundle.js',
        chunkFilename: '[name].bundle.js'
    }    
}
publicPath-静态资源访问

对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片、文件等)来说,output.publicPath 是很重要的选项。如果指定了一个错误的值,则在加载这些资源时会收到 404 错误。

eg.

module.exports = {
    // ...
    output: {
        // 以下是所有可能的值
        publicPath: 'auto',
        // https协议的CDN资源地址
        publicPath: 'https://cdn.eg.com/assets/',
        // 使用当前协议的CDN地址
        publicPath: '//cdn.eg.com/assets/'
        // 相对于服务
        publicPath: '/assets/',
        // 相对于HTML页面
        publicPath: 'assets/',
        // 相对于HTML页面
        publicPath: '../assets/',
        // 相对于HTML页面(目录相同)
        publicPath: '',
    }
}

才疏学浅,欢迎指出错误、作补充