Vue-Cli
为了用命令创建一个项目模板,将一些配置默认配置到里面,或者创建项目时,让开发者选择配置以生成项目。
1.将webpack的打包功能配置到模板中
步骤:
创建一个模板目录dd
在目录中使用命令 npm init
yarn add webpack minimist -D
添加bin/index.js,并添加配置到package.json中
添加webpack.config.js文件
创建一个项目目录demo
npm init
yarn
创建一个index.js作为入口文件
在package.json中添加命令"build": "dd" (dd为模板项目的项目名)
在dd目录下,npm link
在demo目录下,npm link dd
在demo目录下打包,查看是否打包成功
相关代码:
// bin/index.js
#!/usr/bin/env node
const webpack = require('webpack');
const builtInWebpackConfig = require('../webpack.config');
const runWebpackBuild = () => {
webpack(builtInWebpackConfig,( err, stats ) => {
if(err || stats.hasErrors()) {
return console.log("build err!")
}
console.log("build success!")
})
}
runWebpackBuild()
// webpack.config.json
module.exports = {
entry: "./index.js",
output: {
filename: "bundle.js",
}
}
2.让项目可以配置自定义文件,模板中读取自定义文件
思路:
因为配置的自定义文件中有多种配置文件,我们可以读取文件后,抛出去一个api对象,传入到每个配置。大部分的插件配置都是这样做的
步骤:
首先比如我们想自定义一个命令,和一些webpack配置
那我们首先在生成的项目中的package文件中自定义一个命令clear
然后我们在模板的bin文件中定义一下我们的配置文件名称,并读取文件
const fname = "moban.config.js";
const readInConfig = () => new Promise((resolve, reject) => {
const config = require(path.join(process.cwd(),fname)); //读取到文件配置
const { plugins: { command = [], webpack = {} } = {} } = config;
...
resolve();
})
读取到文件的配置后,现在定义一下处理文件中command和webpack的api
const _commands = {};
const _webpackConfig = {}
const api = {
registerCommand(name, impl) {
const command = _commands[name];
if(!command) {
_command[name] = impl;
}
},
chainWebpack(name, impl) {
const config = _webpackConfig[name];
if(!config) {
_webpackConfig[name] = impl;
}
}
...
}
读取文件后循环文件中的配置,将我们写好的api暴露给文件中的配置,让他们可以自由的选择配置所使用的功能
为什么读取文件后不将配置拿进来通过api方法处理,而是将方法抛出去让各个配置自己去调用?
因为将功能模块和调用对象分开成独立的模块,可以更自由的调用和明明,能更好地复用和维护。
将功能模块定义在模板里,也能让配置模块的功能更加清晰,也避免了各个用户配置功能的差异,并且让模板内部的数据变得唯一可控。
const fname = "moban.config.js";
const readInConfig = () => new Promise((resolve, reject) => {
const config = require(path.join(process.cwd(),fname)); //读取到文件配置
const { plugins: { commands = [] } = {} } = config;
if(command.length > 0) {
commands.forEach(command => command(api));
}
resolve();
})
读取文件,将读取后最终拿到的配置_commands调用
const args = require(minimist(process.argv.slice(2)));
readInConfig().then(() => {
// 首先,在调用命令时,我们能拿到命令的参数,也就是_command的name
const name = args._[0]; // args: { _: ["clear"] }
const command = _commands[name];
if(command) {
command();
} else {
runWebpackBuild(); // 如果自定义的命令没有注册进模板,就执行打包命令
}
})
在模板生成的文件下,写个配置文件测试一下
// /moban.config.js
const clearCommand = require('./plugins/clear.command.js');
module.exports = {
plugins: {
command: [clearCommand("Hello World")]; // 一般在外层再包一层函数,可以自由传入一些东西
}
}
// /plugins/clear.command.js
module.exports = (o) => (api) => {
api.registerCommand('clear', () => {
console.log("clear success!", o)
})
}
输入npm run clear, 看是否打印成功。。。