一次Webpack配置文件的分离实战记录


Posted in Javascript onNovember 30, 2018

前言

随着前端技术的发展,业务逻辑的增多及功能化的繁琐已经成为前端人员最烧脑的问题。前端自动化构建工具的出现,为前端人员带来了项目构建上的福音,成为每个前端工程师必回的技术栈,目前比较流行的Webpack以万物皆模块的思想构建我们的前端项目,同样也是笔者正在使用的一个前端自动化构建工具。

Webpack对于每个前端人员来说都不会怎么陌生,它将每一个静态文件当做一个模块,经过一系列的处理为我们整合出最后的需要的js、css、图片、字体等文件。

webpack.config.js就是Webpack的配置文件,这个文件需要自己在项目根目录下手动建立。

下面话不多说了,来一起看看详细的介绍吧

单个配置文件所造成的问题

本文默认电脑前的你已经了解一些Webpack基础的配置,并懂得了webpack.config.js配置文件的基础搭建。

随着我们业务逻辑的增多,图片、字体、css、ES6以及CSS预处理器和后处理器逐渐的加入到我们的项目中来,进而导致配置文件的增多,使得配置文件书写起来比较繁琐,更严重者(书写特定文件的位置会出现错误)。更由于项目中不同的生产环境和开发环境的配置,使得配置文件变得更加糟糕。

使用单个的配置文件会影响到任务的可重用性,随着项目需求的增长,我们必须要找到更有效地管理配置文件的方法。

管理配置文件的几种方法

配置文件的管理有一下几种方法。

  • 在每个环境的多个文件中维护配置,并通过--config参数将webpack指向每个文件,通过模块导入共享配置。
  • 将配置文件推送到库,然后引用库。
  • 将配置文件推送到工具。
  • 维护单个配置文件的所有配置并在那里进行分支并依赖--env参数。

本文以第四种方式阐述webpack配置文件的分离。

分离配置文件

我们在根目录下创建config文件夹,并创建四个配置文件,分别是:

  • webpack.comm.js   公共环境的配置文件
  • webpack.development.js    开发环境下的配置文件
  • webpack.production.js     生产环境下的配置文件
  • webpack.parts.js      各个配置零件的配置文件

一次Webpack配置文件的分离实战记录

合并配置文件的工具

如果配置文件被分成了许多不同的部分,那么必须以某种方式来组合他们,通常就是合并数组和对象,webpack-merge很好的做到了这一点。

webpack-merge做了两件事:它允许连接数组并合并对象,而不是覆盖组合。

const merge = require("webpack-merge");
merge(
 {a : [1],b:5,c:20},
 {a : [2],b:10, d: 421}
)
//合并后的结果
{a : [1,2] ,b :10 , c : 20, d : 421}

使用webpack-merge合并配置文件

首先将webpack-merge添加到项目中

npm install webpack-merge --save-dev

首先设置各个配置文件的连接

webpack.config.js

const commConfig = require("./config/webpack.comm");
const developmentConfig = requie("./config/webpack.development");
const productionConfig = require("./config/webpack.development")
const merge = require("webpack-merge");

module.exports = mode => {
 if(mode === "production"){
  return merge(commConfig,productionConfig,{mode}); 
 }
 return merge(commConfig,developmentConfig,{mode});
}

上面代码利用mode的值来判断是开发环境还是生产环境

webpack.comm.js

const merge = require("webpack-merge");
const parts = require("./webpack.parts") //引入配置零件文件
const config = {
 //书写公共配置 
}
module.exports = merge([
 config,
 parts......
])

webpack.production.js

const merge = require("webpack-merge");
const parts = require("./webpack.parts"); //引入配置零件文件
const config = {
 //书写公共配置
}
modules.exports = merge([
 config,
 parts......
])

webpack.development.js

const merge = require("webpack-merge");
const parts = require("./webpack.parts"); //引入配置零件文件
const config = {
 //书写公共配置
}
modules.exports = merge([
 config,
 parts......
])

使用--env值传参

使用--env允许将字符串传递给配置。我们来修改下package.json

"dev": "webpack --env development ",
 "prod": "webpack --env production",
 "dev:server": "webpack-dev-server --env development "

这样就使得env参数mode环境参数传入到webpack.config.js中,就可以判断是生产环境还是开发环境。

如何写出可配置的webpack.parts.js

上面可以看出我们新建了一个webpack.parts.js文件,这个文件中主要是存放我们的一些配置零件。如何写出可配置,可拔插的配置零件。就是我们这个文件的最重要的部分。

以loadCSS为例:

exports.loadCSS = ({reg = /\.css$/,include,exclude,uses = []} = {}) => ({
 module : {
  rules:[{
   test : reg,
   include,
   exclude,
   use[{
    loader : "style-loader",
   },{
    loader : "css-loader",
   }].concat(uses),
  }]
 }
})

上面代码中,利用exports导出单个配置零件,通过解构赋值来传入参数。使用数组的concat来连接外部导入的loader。参数解析:

  • reg:表示loader匹配的test正则,默认为css,这里可以是(less、sass、stylus)。
  • include:表示所要打包的文件夹。
  • exclude:表示要跳过打包的文件夹。
  • uses:外部导入的loader。

在webpack.development.js中引入

module.exports = merge([
 config,
 parts.loadCSS({
  reg : /\.less/,
  use : ["less-loader"]
 }),
 parts.loadCSS(),
])

分离配置文件的好处

配置文件拆分可以是我们继续扩展配置。最重要的收益是我们可以提取不同目标之间的共性。并且还可以识别要组合的较小配置部件,这些配置不见可以推送到自己的软件包以跨项目使用。还可以将配置作为依赖项进行管理,而不是在多个项目中复制类似的配置。

我自己的parts配置

展示一部分我自己的部件配置,由于在学习阶段,不足的地方还望大佬们提出,学习进步。

/**
 * @name 本地服务器配置
 * @param host 打开的url
 * @param port 打开url的端口号
 * 
 */
exports.devServer = ({ host, port} = {}) => ({
 devServer : {
  stats : "errors-only",
  host,
  port,
  open : true,
  overlay : true,
 }
})
/**
 * @name 未从js中分离的cssLoader配置
 * @param reg 匹配文件的后缀名test
 * @param include 所要打包的文件夹
 * @param exclude 跳过打包的文件夹
 * @param uses 所要向loadCSS中添加的loader
 */
exports.loadCSS = ({reg = /\.css$/,include,exclude,uses = []} = {}) => {
 return {
  module: {
   rules: [{
    test: reg,
    use: [{
     loader: "style-loader"
    }, {
     loader: "css-loader"
    }].concat(uses),
    include,
    exclude,
   }]
  },
 }
}
/**
 * @name 从js中分离的cssLoader配置
 * @param reg 匹配文件的后缀名test
 * @param include 所要打包的文件夹
 * @param exclude 跳过打包的文件夹
 * @param uses 所要向loadCSS中添加的loader
 * */
const MiniCssExtrectPlugin = require("mini-css-extract-plugin");
exports.extractCSS = ({reg = /\.css$/,include,exclude,uses = []} = {}) => {
 const plugin = new MiniCssExtrectPlugin({
  filename : "styles/[name]-[hash:5].css",
 })
 return {
  module: {
   rules: [{
    test: reg,
    use: [{
     loader: MiniCssExtrectPlugin.loader,
     options : {
      publicPath : "../"
     }
    }, {
     loader: "css-loader"
    }].concat(uses),
    include,
    exclude,
   }]
  },
  plugins : [
   plugin,
  ]
 }
}
/**
 * @name css tree-shaking:将没有用到的css扔掉
 * @param paths 监听css tree-shaking 的文件名
 */
const PurifyCssPlugin = require("purifycss-webpack");
exports.purifyCSS = ({paths}) => ({
 plugins : [
  new PurifyCssPlugin({paths})
 ]
})

/**
 * @name autoprefixer 为css样式添加浏览器前缀
 * @author wangchong
 */
exports.autoprefix =() =>({
 loader : "postcss-loader",
 options : {
  plugins : () => [require("autoprefixer")]
 }
})

/**
 * @name loadImage :打包图片资源
 * @param include 所要打包的文件夹
 * @param exclude 跳过打包的文件夹
 * @param options loader的options配置
 */
exports.loadImage = ({include,exclude,options} = {}) => ({
 module : {
  rules : [
   {
    test : /\.(png|jpg)$/,
    include,
    exclude,
    use : {
     loader : "url-loader",
     options,
    }
   }
  ]
 }
})

文章总结自:Surviejs-webpack。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript之AJAX框架使用说明
Apr 24 Javascript
JavaScript中创建对象和继承示例解读
Feb 12 Javascript
node.js实现BigPipe详解
Dec 05 Javascript
JS出现失效的情况总结
Jan 20 Javascript
vue绑定设置属性的多种方式(5)
Aug 16 Javascript
Vue 多层组件嵌套二种实现方式(测试实例)
Sep 08 Javascript
微信小程序实现给嵌套template模板传递数据的方式总结
Dec 18 Javascript
基于JavaScript实现幸运抽奖页面
Jul 05 Javascript
解决Vue.js应用回退或刷新界面时提示用户保存修改问题
Nov 24 Javascript
js实现图片上传到服务器和回显
Jan 19 Javascript
深入理解 ES6中的 Reflect用法
Jul 18 Javascript
Vue+Element自定义纵向表格表头教程
Oct 26 Javascript
基于Vue组件化的日期联动选择器功能的实现代码
Nov 30 #Javascript
vue拖拽排序插件vuedraggable使用方法详解
Aug 21 #Javascript
JS实现图片拖拽交换效果
Nov 30 #Javascript
Vue+Webpack完美整合富文本编辑器TinyMce的方法
Nov 30 #Javascript
jQuery实现网页拼图游戏
Apr 22 #jQuery
vue 双向数据绑定的实现学习之监听器的实现方法
Nov 30 #Javascript
基于jquery实现九宫格拼图小游戏
Nov 30 #jQuery
You might like
PHP脚本的10个技巧(7)
2006/10/09 PHP
PHP中防止SQL注入攻击和XSS攻击的两个简单方法
2010/04/15 PHP
php printf输出格式使用说明
2010/12/05 PHP
PHP用GD库生成高质量的缩略图片
2011/03/09 PHP
让Nginx支持ThinkPHP的URL重写和PATHINFO的方法分享
2011/08/08 PHP
PHP模块化安装教程
2016/06/01 PHP
php表单处理操作
2017/11/16 PHP
Javascript YUI 读码日记之 YAHOO.util.Dom - Part.3
2008/03/22 Javascript
javascript控制frame,iframe的src属性代码
2009/12/31 Javascript
javascript动画之圆形运动,环绕鼠标运动作小球
2010/07/20 Javascript
20个非常棒的 jQuery 幻灯片插件和教程分享
2011/08/23 Javascript
详解AngularJS中的作用域
2015/06/17 Javascript
JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
2015/10/10 Javascript
多种JQuery循环滚动文字图片效果代码
2020/06/23 Javascript
JavaScript简单获取页面图片原始尺寸的方法
2016/06/21 Javascript
JavaScript常用代码书写规范的超全面总结
2016/09/11 Javascript
vue2.0多条件搜索组件使用详解
2020/03/26 Javascript
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
2017/10/24 Javascript
JS基于递归实现网页版计算器的方法分析
2017/12/20 Javascript
详解微信小程序开发用户授权登陆
2019/04/24 Javascript
浅析JavaScript 函数柯里化
2020/09/08 Javascript
[01:02:45]完美世界DOTA2联赛 LBZS vs Forest 第三场 11.07
2020/11/09 DOTA
python字典多条件排序方法实例
2014/06/30 Python
Python实现发送email的几种常用方法
2014/08/18 Python
详解Python中for循环的使用方法
2015/05/14 Python
理论讲解python多进程并发编程
2018/02/09 Python
Python实现最大子序和的方法示例
2019/07/05 Python
Python with语句和过程抽取思想
2019/12/23 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
2020/05/29 Python
python+appium+yaml移动端自动化测试框架实现详解
2020/11/24 Python
马来西亚最大的在线隐形眼镜商店:MrLens
2019/03/27 全球购物
交通事故赔偿协议书怎么写
2014/10/04 职场文书
计划生育汇报材料
2014/12/26 职场文书
2015年世界水日活动总结
2015/02/09 职场文书
感恩老师主题班会
2015/08/12 职场文书
导游词之苏州盘门景区
2019/11/12 职场文书