webpack-chain源码 vue-cli配置webpack
栏目: JavaScript · 发布时间: 5年前
内容简介:需要先预习 下列方法如果对这些知识生疏,点此学习 (
git clone https://github.com/neutrinojs/webpack-chain.git 复制代码
知识准备
需要先预习 下列方法
ES6 Set ES6 Map ES6 Class includes reduce map forEach Object.keys Object.assign ...
如果对这些知识生疏,点此学习 ( es6.ruanyifeng.com/#docs/class ) 把这些掌握后,阅读很easy
目录结构
目标是把src 里面的方法都了解会用
└── webpack-chain ├── src │ ├── Chainable.js │ ├── ChainedMap.js │ ├── ChainedSet.js │ ├── Config.js │ ├── DevServer.js │ ├── Module.js │ ├── Optimization.js │ ├── Orderable.js │ ├── Output.js │ ├── Performance.js │ ├── Plugin.js │ ├── Resolve.js │ ├── ResolveLoader.js │ ├── Rule.js │ └── Use.js 复制代码
文件名全是首字母大写,从命名看,每个里面全是类的定义,用 extends
来实现继承
Chainable ChainedMap.js ChainedSet.js
ChainedMap.js
ChainedSet.js
都继承了 Chainable
Chainable 以able 为后缀表示具有什么能力。这个库维护了 parent ,用end来实现链式。很像jq的end().
ChainedMap.js
ChainedSet.js
这两个里面分别包装了 js 原生的 Map, Set 结构。
ChainedMap
// 维护了parent 链,由上文提到的`Chainable`来做的 // 实例化了一个store (仓库) 拥有Map结构的方法 constructor(parent) { super(parent); this.store = new Map(); } // 从 Map 移除所有 配置. clear() // 通过键值从 Map 移除单个配置. // key: * delete(key) // 获取 Map 中相应键的值 // key: * // returns: value get(key) // 都是map的原生方法封装 has(key) + set(key, value) // 传入key 和 函数两个参数 当拥有key的时候 返回获取到的值 如果key 没有定义过,调用函数生成键值对 getOrCompute(key, fn) { if (!this.has(key)) { this.set(key, fn()); } return this.get(key); } 把对象进行清洗,传参数{a:undefined, b: [], c:{}, d:0 } 输出{ d: 0 },会把undefined,[],{}这些过滤掉。 clean(obj) // when的用法 // when 有断言作用,第2,3参数是函数。函数参数就是this。 // config // .when(process.env.NODE_ENV === 'production', // config => config.plugin('minify').use(BabiliWebpackPlugin), // config => config.devtool('source-map') // ); when( condition, whenTruthy = Function.prototype, whenFalsy = Function.prototype ) { if (condition) { whenTruthy(this); } else { whenFalsy(this); } return this; } extend 参数是数组,会批量往this上绑定一些方法, 绑定方法是用的set,说明再次调用会覆盖掉上次。 例如: this.extend(['watch']) 会生成 this.watch = value => this.set(method, value); 复制代码
理解了ChainedMap,那ChainedSet也容易
实战配置vue-cli 项目
用vue-cli3生成项目后
vue inspect > default.json 复制代码
会生成默配置到default.json
这些配置是从这个包 node_modules/@vue/cli-service/lib/config/base.js
生成的
打开这个文件看一下webpack-chain的用法.
vue引入webpack-chain的文件是 node_modules/@vue/cli-service/lib/Service.js
在此文章搜索下面三行
const Config = require('webpack-chain') // 会引入webpack-chain库"src/Config.js"文件 // 只实例化一次,chainWebpack 的config参数就是这个实例 const chainableConfig = new Config() // 会生成配置 let config = chainableConfig.toConfig() 复制代码
我们看一下 webpack-chain
源码 Config.js
文件
toConfig() { // 入口entry const entryPoints = this.entryPoints.entries() || {}; // clean 方法上文Map结构有讲 return this.clean( // this.entries() 全部this.store的值。包含this.extend()方法生成的速记方法 Object.assign(this.entries() || {}, { node: this.node.entries(), output: this.output.entries(), resolve: this.resolve.toConfig(), resolveLoader: this.resolveLoader.toConfig(), devServer: this.devServer.toConfig(), module: this.module.toConfig(), optimization: this.optimization.toConfig(), plugins: this.plugins.values().map(plugin => plugin.toConfig()), performance: this.performance.entries(), entry: Object.keys(entryPoints).reduce( (acc, key) => Object.assign(acc, { [key]: entryPoints[key].values() }), {} ), }) ); } 复制代码
修改 entry
chainWebpack: config => { config.entryPoints.clear() // 会把默认的入口清空 config.entry('main').add('./src/main.js') config.entry('routes').add('./src/app-routes.js') } 链式调用:end方法 clear方法会把vue-cli默认的.entry('app')清空。可以在同一个chunk,add多个模块。 config.entryPoints.clear().end() .entry('main').add('./src/main.js').end() .entry('routes').add('./src/app-routes.js') 复制代码
vue inspect > entry.json
对比entry.json和default.json的entry字段,成功修改。
- 速记方法 看上文Map extend 介绍
用速记方法修改简单的字段
config.mode('production') config.watch(true) 生成文件,查看已变成 mode: 'production', watch: true, 复制代码
用速记方法修改proxy
chainWebpack: config => { config.devServer.port(9898) .open(true) .proxy({'/dev': { target: 'http://123.57.153.106:8080/', changeOrigin: true, pathRewrite: { '^/dev': '' } } }) } 复制代码
用速记方法修改output
chainWebpack: config => { config .when(process.env.NODE_ENV === 'production', config => { config.output.publicPath('//busi.cdnimg.com/demo-finance/dist/') }); } 复制代码
添加7牛plugin
const QiniuPlugin = require('qn-webpack') chainWebpack: config => { config.plugin('7niu') .use(QiniuPlugin,[{ accessKey: '1234567654356', secretKey: '2344344545', bucket: 'busi-cdn', path: 'cdn-finance/dist/', exclude: /index\.html$/ // 排除特定文件,正则表达式 }]); } 通过阅读Plugin.js源码toConfig方法,发现还可以传字符串类型,还有对象实例 const init = this.get('init'); // 会调用init(plugin, args); 把插件函数和参数传入 let plugin = this.get('plugin'); // 获取plugin const args = this.get('args');// 获取参数 config .plugin('7niu') .use('qn-webpack',[{ accessKey: '1234567654356', secretKey: '2344344545', bucket: 'busi-cdn', path: 'cdn-finance/dist/', exclude: /index\.html$/ // 排除特定文件,正则表达式 }]); 生成的效果 /* config.plugin('7niu') */ new (require('qn-webpack'))( { accessKey: '1234567654356', secretKey: '2344344545', bucket: 'busi-cdn', path: 'cdn-finance/dist/', exclude: /index\.html$/ } ) 复制代码
添加clear plugin
用对象实例的方式
const CleanPlugin = require("clean-webpack-plugin"); const clean = new CleanPlugin() config .plugin('clean').use(clean) 复制代码
添加 删除loader
把vue的loader 都删掉
config.module .rule('vue').uses.clear() 复制代码
添加loader
从 @vue/cli-service/lib/config/base.js
的一段代码来参考
webpackConfig.module .rule('images') .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/) .use('url-loader') .loader('url-loader') .options(genUrlLoaderOptions('img')) 复制代码
单独调试
const Config = require('webpack-chain'); const config = new Config(); const CleanPlugin = require("clean-webpack-plugin"); config .plugin('clean') .use(CleanPlugin); let r = config.toConfig() console.log(r) 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 源码分析(五)—配置篇
- 源码安装配置 Nginx 记录
- Nginx 源码:配置文件解析
- Nacos 源码分析(二):获取配置流程
- mybatis原理,配置介绍及源码分析
- Nginx源码阅读笔记-配置解析流程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JavaScript基础教程
Tom Negrino、Dori Smith / 陈剑瓯 / 人民邮电出版社 / 2007-9 / 45.00元
《JavaScript基础教程》(第6版)循序渐进地讲述了JavaScript 及相关的CSS、DOM与Ajax 等技术。书中从JavaScript 语言基础开始,分别讨论了图像、框架、浏览器窗口、表单、正则表达式、用户事件和cookie,还有两章讲述了Ajax 基础。《JavaScript基础教程》(第6版)不仅有对于基础知识和使用方法的介绍,也包含了对JavaScript 应用示例的深入探讨。一起来看看 《JavaScript基础教程》 这本书的介绍吧!