Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gulp babili #318

Merged
merged 8 commits into from Mar 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/gulp-babili/.npmignore
@@ -0,0 +1,4 @@
src
__tests__
node_modules
*.log
41 changes: 41 additions & 0 deletions packages/gulp-babili/README.md
@@ -0,0 +1,41 @@
# gulp-babili

## Installation

```sh
npm install gulp-babili --save-dev
```

## Usage

```js
const gulp = require("gulp");
const babili = require("gulp-babili");

gulp.task("minify", () =>
gulp.src("./build/app.js")
.pipe(babili({
mangle: {
keepClassNames: true
}
}))
.pipe(gulp.dest("./dist"));
);
```

## API

```js
gulpBabili(babiliOptions, overrides);
```

### babiliOptions

These are passed on to the babili preset. Refer https://github.com/babel/babili/tree/master/packages/babel-preset-babili#options. Default `{}`

### Overrides

Default: `{}`

+ `babel`: Use a custom `babel-core`
+ `babili`: Use a custom `babel-preset-babili`
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`gulp-babili comments should remove all comments when false 1`] = `"foo(),bar(),baz();"`;

exports[`gulp-babili comments should remove comments by default except license and preserve 1`] = `
/**
* @license
* This is a test
*/"foo(),bar(),baz();"`;

exports[`gulp-babili comments should take a custom function 1`] = `"/* YAC - yet another comment */foo(),bar(),baz();"`;
167 changes: 167 additions & 0 deletions packages/gulp-babili/__tests__/gulp-babili-test.js
@@ -0,0 +1,167 @@
jest.autoMockOff();

const gutil = require("gulp-util");
const babelCore = require("babel-core");
const babiliPreset = require("babel-preset-babili");

const unpad = require("../../../utils/unpad");
const gulpBabili = require("../src/index");

describe("gulp-babili", () => {
it("should work with a good default", () => {
return new Promise((resolve, reject) => {
const stream = gulpBabili();

const source = unpad(`
function foo() {
const a = 10;
return a;
}
`);
const expected = "function foo(){return 10}";

stream.on("data", function (file) {
expect(file.contents.toString()).toBe(expected);
resolve();
});
stream.on("error", reject);

stream.write(new gutil.File({
path: "defaults.js",
contents: new Buffer(source),
}));
});
});

it("should take options and pass them to babili", () => {
return new Promise((resolve, reject) => {
const stream = gulpBabili({
mangle: {
blacklist: {
bar: true
}
}
});

const source = unpad(`
function foo(bar, baz) {
return bar + baz;
}
`);
const expected = "function foo(bar,a){return bar+a}";

stream.on("data", function (file) {
expect(file.contents.toString()).toBe(expected);
resolve();
});
stream.on("error", reject);

stream.write(new gutil.File({
path: "options.js",
contents: new Buffer(source)
}));
});
});

it("should take custom babel and babili", () => {
return new Promise((resolve, reject) => {
const babel = Object.assign({}, babelCore);

let usedTransform = false;
Object.defineProperty(babel, "transform", {
get() {
usedTransform = true;
return babelCore.transform;
}
});

let usedPreset = false;
const babili = function (...args) {
usedPreset = true;
return babiliPreset(...args);
};

const stream = gulpBabili({}, {
babel,
babili,
});

stream.on("data", function () {
expect(usedTransform).toBe(true);
expect(usedPreset).toBe(true);
resolve();
});
stream.on("error", reject);

stream.write(new gutil.File({
path: "custom-transformers.js",
contents: new Buffer("foo()")
}));
});
});

describe("comments", () => {
const source = unpad(`
/**
* @license
* This is a test
*/
foo();
// this is another comment
bar();
/* YAC - yet another comment */
baz();
`);

let file;

beforeEach(() => {
file = new gutil.File({
path: "comments.js",
contents: new Buffer(source)
});
});

xit("should remove comments by default except license and preserve", () => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is disabled as it removes all comments by default.

return new Promise((resolve, reject) => {
const stream = gulpBabili();
stream.on("data", function (file) {
expect(file.contents.toString()).toMatchSnapshot();
resolve();
});
stream.on("error", reject);
stream.write(file);
});
});

it("should remove all comments when false", () => {
return new Promise((resolve, reject) => {
const stream = gulpBabili({
comments: false
});
stream.on("data", () => {
expect(file.contents.toString()).toMatchSnapshot();
resolve();
});
stream.on("error", reject);
stream.write(file);
});
});

xit("should take a custom function", () => {
return new Promise((resolve, reject) => {
const stream = gulpBabili({
comments(contents) {
return contents.indexOf("YAC") !== -1;
}
});
stream.on("data", () => {
expect(file.contents.toString()).toMatchSnapshot();
resolve();
});
stream.on("error", reject);
stream.write(file);
});
});
});
});
21 changes: 21 additions & 0 deletions packages/gulp-babili/package.json
@@ -0,0 +1,21 @@
{
"name": "gulp-babili",
"version": "0.0.1",
"description": "Gulp Babili",
"homepage": "https://github.com/babel/babili#readme",
"repository": "https://github.com/babel/babili/tree/master/packages/gulp-babili",
"bugs": "https://github.com/babel/babili/issues",
"author": "boopathi",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-preset",
"babili"
],
"dependencies": {
"babel-core": "^6.22.1",
"babel-preset-babili": "^0.0.10",
"vinyl-sourcemaps-apply": "^0.2.1"
},
"devDependencies": {}
}
91 changes: 91 additions & 0 deletions packages/gulp-babili/src/index.js
@@ -0,0 +1,91 @@
const babelCore = require("babel-core");
const through2 = require("through2");
const gutil = require("gulp-util");
const applySourceMap = require("vinyl-sourcemaps-apply");
const babiliPreset = require("babel-preset-babili");

const { PluginError } = gutil;

const NAME = "gulp-babili";

module.exports = gulpBabili;

function gulpBabili(babiliOpts = {}, {
babel = babelCore,
babili = babiliPreset,
comments = /preserve|licen(s|c)e/
} = {}) {
return through2.obj(function (file, enc, callback) {
if (file.isNull()) {
return callback(null, file);
}

if (file.isStream()) {
return callback(new PluginError(NAME, "Streaming not supported"));
}

let inputSourceMap;
if (file.sourceMap && file.sourceMap.mappings) {
inputSourceMap = file.sourceMap;
}

const babelOpts = {
minified: true,
babelrc: false,
ast: false,

/* preset */
presets: [ [ babili, babiliOpts ] ],

/* sourcemaps */
sourceMaps: !!file.sourceMap,
inputSourceMap,

shouldPrintComment(contents) {
return shouldPrintComment(contents, comments);
},

/* file */
filename: file.path,
filenameRelative: file.relative,
};

const { result, success, error } = transform({
babel,
input: file.contents.toString(),
babelOpts
});

if (success) {
file.contents = new Buffer(result.code);
if (file.sourceMap) {
applySourceMap(file, result.map);
}
return callback(null, file);
}

callback(error);
});
}

function transform({ babel, input, babelOpts }) {
try {
return {
success: true,
result: babel.transform(input, babelOpts)
};
} catch (e) {
return {
success: false,
error: e
};
}
}

function shouldPrintComment(contents, predicate) {
switch (typeof predicate) {
case "function": return predicate(contents);
case "object": return predicate.test(contents);
default: return !!predicate;
}
}