编写gulp、webpack与fis3插件
在工作中接触了不少打包和环境构建工具,如gulp
、webpack
以及现在公司使用的fis3
等,每个工具都有自己的社区和生态,并提供相关的功能插件,如编译sass、babel转移、压缩代码等。
在某些特定的需求和开发环境下,社区的插件并不能很好地满足开发生产需求(比如需要自定义打包过程的控制台输出、在编译scss文件前注入公共的scss变量代码等),因此需要了解对应工具的插件编写,这里整理一下。
参考
编写gulp插件
我们知道gulp是基于文件流的任务管理工具,编写gulp插件可以通过through2来实现。
// gulp-demo.js
let through2 = require('through2');
module.exports = function () {
return through2.obj(function (file, encoding, cb) {
// 这里可以做一些内容校验
// ..
// 获取文件内容
let content = file.contents.toString();
// 处理内容
let res = demoHandler(content);
// 完成后需要转换回buffer类型
file.contents = new Buffer(res);
//下面这两句基本是标配,可参考through2的API
this.push(file);
cb();
});
}
function demoHandler(data) {
return data.replace(/{{.*?}}/, "xxx");
}
ran'ho
然后编写gulp任务,在pipe中调用插件处理文档内容即可
// gulpfile.js
let gulpDemo = require('./dev/gulp-demo');
gulp.task('demo', function(){
gulp.src('src/test.txt')
.pipe(gulpDemo())
.pipe(gulp.dest('./dist'));
})
编写webpack loader
loader 是导出为一个函数的 node 模块。该函数在 loader 转换资源的时候调用。给定的函数将调用 loader API,并通过
this
上下文访问。
从描述可见webpack的loader与gulp的插件工作编写比较相同。下面是实例代码,编写对应的模块
// rem-loader.js
module.exports = function (source) {
// 可以通过this访问到webpack上下文
// 这里对文件内容进行一些处理
let remScss = `
@function rem($px) {
@if (unitless($px)) {
@return 1rem * ($px/100);
} @else {
@return 1rem * ($px/100px);
}
}
`;
source = `${remScss} \n ${source}`;
// 将内容导出到下一个loader
return source;
}
然后在配置文件引入对应loader即可
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: page1ExtractTextPlugin.extract({
use: [
"css-loader",
"autoprefixer-loader",
"sass-loader",
path.resolve("./dev/rem-loader.js")
]
})
}
];
}
}
编写webpack plugin
webpack插件可以在webpack打包过程中调用相关的钩子函数,并进行相关逻辑处理。
下面插件是官方demo里面的代码,会在webpack
指令执行完毕后在控制台输出文案
class HelloWorldPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.done.tap('HelloWorldPlugin', () => {
console.log('Hello World!');
console.log(this.options);
});
}
}
module.exports = HelloWorldPlugin;
然后在配置文件调用即可
let HelloWorldPlugin = require('./dev/hello-world-plugin.js')
module.exports = {
// ...
plugins: [
new HelloWorldPlugin()
]
}
编写fis3插件
fis3中,每一个File对象都要经过编译、打包、发布三个阶段,对应的插件基本使用方式为
fis.match('xx.xx', {
<type>: fis.plugin('<name>', {
//conf
})
})
其中的type类型有
编译阶段插件,包括
lint
、parser
、preprocessor
、postprocessor
、optimizer
等插件扩展点js// 编译阶段插件的基本形式 module.exports = function (content, file, settings) {}
打包阶段插件,包括
prepackager
、packager
、spriter
、postpackager
等插件扩展点js// 打包阶段插件的基本形式 module.exports = function (ret, conf, settings, opt) {}
部署阶段插件,包含
deploy
插件扩展点js// 部署阶段插件的基本形式 module.exports = function(options, modified, total, next) {}
fis3是一套完整的前端工程化开发方案,如果仅仅是为了处理开发环境的需求,一般只需要关注编译阶段插件即可。
以对js文件进行babel处理为例,编写fis3-parser-translate-es6
插件
// node_modules/fis3-parser-translate-es6/index.js
var babel = require('babel-core');
module.exports = function (content, file, options) {
var result = babel.transform(content, options);
return result.code; // 处理后的文件内容
}
然后在fis-conf.js
文件中进行声明,由于该插件是编译类型插件,在parser
扩展点调用该插件即可
fis.media('prod').match("*.es6.js", {
parser: fis.plugin("translate-es6", {
presets: ["env"]
}),
});
小结
这里整理了我在工作中用到的几种流程工具的插件开发,虽然目前还在维护一些grunt构建的项目,但是更新频率比较低,因此这里就没有整理grunt相关的插件开发方案。
除此之外,现在各个主流框架基本都内置了脚手架工具,如react-create-app
、vue-cli3
等,绕开了基础的开发环境配置。
但是,了解开发环境的搭建,还是前端的基本功,因此了解插件的开发还是很有必要的,整理在这里,方便后面自己查阅。
你要请我喝一杯奶茶?
版权声明:自由转载-非商用-保持署名和原文链接。
本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。