Liaoct / blog

在这里记录一些个人经验与思考
22 stars 2 forks source link

前端脚手架 #21

Open ghost opened 5 years ago

ghost commented 5 years ago

我们有自己的前端脚手架啦~(≧▽≦)/~

到目前为止,我们前端的基础框架的搭建仍然是一个很繁琐的过程。 尤其是最近几天,我准备搭建一个vue的基础开发框架,但是我需要在隔壁互联网机器上搭建好了,然后拷贝到我的开发机上。

在搭建的过程中,并不是一次性就能所有的配置都能够搭建完整并且没有错误,因此我需要隔壁两个房间来回跑。然后在做技术预研时,许多时候我需要一个干净的初始工程,然后继续工作,但是往往不尽如愿。

另外一个值得考虑的事情,我们不管是在做学习任务,或者是要开启新项目时,都希望能够有一套完整的、统一的、规范的、易用的、干净的基础框架,以便能够快速的开始工作。

但是,这里存在一些问题:

  1. 我们在内网环境,并不能直接使用诸如vue-cli等这样的官网脚手架,他们需要从互联网下载模板文件。因此,我们需要一个能够在内网环境直接使用的脚手架。
  2. 官网的脚手架生成的项目,并完全就是我们想要的,比如,我们特殊的代码规范插件,特殊的语法支持,特殊的目录结构等等。为了便于大家一键生成统一的、适用于我们特殊要求的基础框架,我们需要一个我们自己的脚手架。
  3. 难道你想自己手动去配置一遍基础框架?然后纠结在目录结构、插件版本、代码规范等等这些问题上?

基于以上原因,我决心做一套适用于我们自己的脚手架工具。

screensnap

如图,上面的slush-wst-vue-generator就是我开发vue的脚手架工具。

顺便提一句,其他的包基本都是我修复过的BUG,然后重新提交到我们本地npm仓库的。比如gulp-template,我就修改了一个BUG,然后重新提交了v0.1.3版本,这个工具包实际上在我们的脚手架开发中要用到,后面再介绍。

怎么使用?

我们的脚手架工具采用slush这个工具进行编写的。因此,首要的是安装slush:

yarn global add slush

注意,请先把registry设置为了我们的npm仓库。关于如何管理我们的registry的config设置,后续我会介绍一个工具nrm。

有了slush,我们就可以去安装我们需要的脚手架包了。现在我已经发布了一个slush-wst-vue-generator,去安装它吧:

yarn global add slush-wst-vue-generator

有了脚手架包就可以一键生成项目了。进入到一个目录,使用脚手架开始一个项目:

//创建一个新目录
mkdir slush-demo && cd slush-demo
//使用脚手架开始一个新项目
slush wst-vue-generator

注意:这里我们安装的脚手架包叫做slush-wst-vue-generator,但是在使用该包时不需要slush前缀,直接使用slush命令执行即可。

执行如上命令,会要求你输入一些信息,如下所示,按你的意愿填写。

screensnap2

问题的最后会要求你输入npm的仓库地址,让脚手架知道到哪里去下载依赖包。这里默认是我们的本地npm仓库。

当确认“continue”之后,脚手架会自动安装项目依赖包。并且在目录slush-demo下生成了一个完整的干净的项目。

screensnap6

当依赖完成,你就可以通过阅读readme.md来开始你的项目了。对于上面那个脚手架,你可以这样来运行项目:

yarn run dll//先进行vendor打包
yarn start //运行项目

至此,搭建基础框架这一步都帮你用工具搞定了,你只需要敲敲命令就行了。

怎么开发一个脚手架?

脚手架既然这么好用,那么怎么开发一个脚手架呢?

首先,脚手架就是一个普通的npm包,只需要满足以下几点:

  1. 名字以slush-*开头
  2. package中包含一个slushfile.js文件
  3. package.json中的keywords要有"slushgenerator"关键字
  4. 要生成的模板文件放在templates文件夹中
  5. 安装gulp作为依赖

那么slushfile.js,以及模板文件要怎么编写呢?别着急,这里有一个工具它可以帮你生成一个基本的目录。

slush-generator是一个帮你生成脚手架的脚手架。它可以帮你生成通用的slushfile.js文件和目录结构。

还记得脚手架的使用过程吗?

yarn global add slush-generator //安装脚手架
mkdir slush-wst-demo-generator && slush-wst-demo-generator //在这个目录下去开发一个脚手架
slush generator // 让slush-generator帮你生成基本的目录结构和slushfile.js
... 然后同样的会让你回答一些问题和安装依赖

执行完毕的目录结构长这样:

screensnap3

其中slushfile.js文件中是一些gulp相关的配置。在这里进行诸如模板中变量替换、重命名、将模板文件输出到用户目录等操作,当然那些让你回答的问题也是在这里定义的。

另外一个templates目录,就是我们需要输出到用户目录的模板文件,这里放置的就是那些你想要统一管理的文件。甚至允许你进行一些变量替换。

screensnap4

例如的package.json文件中有<%= appName %>这样的代码,这些变量会在用户使用脚手架时从命令行的输入进行替换。

具体有哪些可以使用的变量呢?它们都定义在slushfile.js中。

screensnap5

例如,这里就定义了一些变量,它们通过用户在命令行的输入得来,或者具有有一些默认值。你可以自己定义你想要的参数,具体参考inquirer模块。

另外如babelrc文件,实际上它是.babelrc,只不过为了防止这些配置文件影响到我们的templates下的文件,要将“.”替换为“\”,这个下划线在最后输出的时候会再次被替换为点号。

模板中的<%= appName %>会通过lodash.template进行模板替换,因此lodash.template支持的模板语法,均可进行使用。如<% if() { %> something <% } %>这样的表达式语法。

templates文件夹开发好了,就可以进行发布你的脚手架了。

发布也是相当简单,在package.json中设置一个合适的version,然后执行如下命令进行发布

npm publish

如果发布成功,你就可以在我们的npm仓库列表上看到你发布的脚手架了,其他同事就可以下载你的脚手架开始一个工程了。

可能遇到的问题?

实际上要开发一个完备的脚手架当然不会如此轻松,首先你要明白gulp流,当然绝大多数时候你是不需要关心的。然后要会使用inquirer模块来定义里自己的变量与问题。要会使用lodash.template来定义你的模板。

我在开发这个脚手架的工程中,当然也遇到了一些问题,所以我才要去修复一些模块的BUG。比如:gulp-template模块,这个模块会使用lodash.template来将templates文件夹下的文件进行模板编译,把形如<%= appName %>这样的插值替换为我们实际的值,但是它默认会把es6中的模板字符串${}也进行编译,这样我们在templates文件夹下的所有${}都会出错。但是我们要使用es6语法,因此,我将这个插件进行了改写。

'use strict';
var gutil = require('gulp-util');
var through = require('through2');
var _ = require('lodash');
var interpolate = require('lodash._reinterpolate');
var template = _.template;

module.exports = function (data, options) {
    if (!options.allowEsInterpolate) {
        _.templateSettings.interpolate = options.interpolate || interpolate; // change default interpolate behaving.
    }
    return through.obj(function (file, enc, cb) {
        if (file.isNull()) {
            this.push(file);
            return cb();
        }

        if (file.isStream()) {
            this.emit('error', new gutil.PluginError('gulp-template', 'Streaming not supported'));
            return cb();
        }

        try {
            file.contents = new Buffer(template(file.contents.toString(), options)(data));
        } catch (err) {
            this.emit('error', new gutil.PluginError('gulp-template', err, {fileName: file.path}));
        }

        this.push(file);
        cb();
    });
};

重新发布后的版本为gulp-template v0.1.3。主要是增加一个可以控制的参数allowEsInterpolate。

这个参数需要在slushfile.js文件中传递到gulp-template。实际上我已经将slush-generator也进行了改写和重新发布,版本号为2.0.0-rc。

大家在使用时,只需要安装slush-generator@2.0.0-rc就能安全的进行脚手架开发。

后续计划完善react相关的脚手架工具