入门webpack的最佳实践(基于webpack4.X 5.X)-- 多入口多环境

127 阅读2分钟

导语

来到这家公司之后,一直在使用webpack,也写了不少笔记,但是都比较零散,现在决定整理一下webpack相关的知识点,由浅入深,方便自己后续查漏补缺,后续会一直更新。

目录

在基础篇中,我们已经构造好了入口,出口,loader,以及js压缩和css压缩分离等基础配置,在本文中,将从以下几个方法进行配置的优化。

  • 多入口打包
  • 多环境打包

基础篇传送:juejin.cn/post/713310…

多入口打包

现在我们开发的大部分应用都是单页面应用,在单页面打包时,我们的配置是

{
    entry: path.resolve(__dirname, 'src/index.jsx'),
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: '[name].[chunkhash].js',
      publicPath: '/',
    },
}

而多页面应用,如电商应用,打包之后有多个互不影响的页面,所以我们需要修改入口配置为多个入口,这里可以直接将enrty改成数组,如

{
    entry: path.resolve(__dirname, 'src/home/index.jsx','src/login/index.jsx'),
}

如果这样修改的话,我们每次新加页面都需要修改这里的配置,扩展性非常的差,正确的处理方法是,可以用正则来匹配根文件夹下的目录,每一个目录代表一个页面,比如,我们的工程目录是这样的,

图片.png

这里有两个页面home,login,那么我们可以这样来匹配入口

const setMpa = () => {

  // 多页面打包的入口集合
  const entry = {};

  // 多页面打包的模板集合
  const htmlWebpackPlugins = [];

  // 借助 glob 获取 src 目录下的所有入口文件
  const entryFiles = glob.sync(path.resolve(__dirname, './src/*/index.jsx'));

  // 遍历文件集合,生成所需要的 entry、htmlWebpackPlugins 集合
  entryFiles.map((item, index) => {
    const match = item.match(/src\/(.*)\/index\.jsx$/);
    const pageName = match?.[1];
    entry[pageName] = item;
    // 多页面所需要的模板集合
    htmlWebpackPlugins.push(
      new HtmlWebpackPlugin({
        title: pageName,
        filename: `${pageName}.html`,
        template: path.join(__dirname, `src/index.html`),
        chunks: [pageName],
      }),
    );
  });
  // 对外输出页面打包需要的 入口集合
  return { entry, htmlWebpackPlugins };
};

和入口文件一样,我们的html也需要打包多份,这里我们用的是同一个模板,如果每个入口文件所用到的html模板不同,只需要在template属性中,修改文件的路径为页面目录即可。

 template: path.join(__dirname, `src/${pageName}/index.html`),

多环境打包

在开发的过程中,我们时常需要针对不同的业务来配置不同的环境来打不同的包,比如

  • dev(开发环境)
  • pro(生产环境)
  • release(发布环境)

以前我们可能会使用一个全局config文件,然后针对不同的环境来修改里面的变量,在wbepack5中,我们只需要在打包的时候传入不同的变量,便可以配置不同环境的打包流程。

在package.json中加入

script:{
    "build:dev": "webpack --mode development  --env mode=development",
    "build:pro": "webpack --mode production  --env mode=production",
}

--env mode=development 代表需要传入到webpack.config.js中的变量

然后在webpack.config.js中,我们通过导出一个方法,来接收传入的参数,方法返回我们的配置信息

module.exports = (webpackEnv) => {
    console.log(webpackEnv) // {mode:xxx}
}

这样就能拿到我们打包的参数,然后我们创建出不同环境的.env文件

图片.png

通过拿到的参数,我们可以很轻松的获取对应文件,然后读取相应的配置

  const { mode } = webpackEnv;
  //通过mode环境变量,获取对应配置文件
  const dotenvFile = `process.${mode}.env`;
  let env = {};
  //判断文件是否存在
  if (fs.existsSync(dotenvFile)) {
    env = dotenv.parse(fs.readFileSync(dotenvFile));
  } else {
    throw new Error('错误的环境变量:' + mode);
  }

  // 将配置文件转化为对象
  const raw = Object.keys(env).reduce((_env, key) => {
    _env[key] = JSON.stringify(env[key]);
    return _env;
  }, {});

最后通过webpack.definePlugin插件,将所有的配置项注入到全局中

...
plugin:[
      // 全局注入环境变量
      new webpack.DefinePlugin({
        'process.env': raw
      }),
]

然后我们就可以在项目的文件中,通过 process.env.XXX 来访问配置信息

注意一下,在webpack5之前,要定义全局的环境变量,使用--env.key=value的语法,现在使用--env key=value

项目链接

github.com/AdolescentJ…

最后

感谢你能看到这里,本文总结了webpack中的多入口多环境配置,希望这篇文章对你有所帮助,后续会陆续更新其他webpack相关的文章,如果能留下你的一个赞,笔者将感激不尽。