Mirror: 🎩 A tiny but capable push & pull stream library for TypeScript and Flow

Move bs-platform minification to chunk plugin

+4 -89
rollup.config.js
···
import { terser } from 'rollup-plugin-terser';
import compiler from '@ampproject/rollup-plugin-closure-compiler';
const cwd = process.cwd();
const pkgInfo = require('./package.json');
const name = basename(pkgInfo.main, '.js');
···
},
});
-
const unwrapStatePlugin = ({ types: t }) => ({
-
pre() {
-
this.props = new Map();
-
this.test = (node) =>
-
/state$/i.test(node.id.name) ||
-
(node.init.properties.length === 1 && node.init.properties[0].key.name === 'contents');
-
},
-
visitor: {
-
VariableDeclarator(path) {
-
if (
-
t.isIdentifier(path.node.id) &&
-
t.isObjectExpression(path.node.init) &&
-
path.node.init.properties.every(
-
(prop) => t.isObjectProperty(prop) && t.isIdentifier(prop.key)
-
) &&
-
this.test(path.node)
-
) {
-
const id = path.node.id.name;
-
const properties = path.node.init.properties;
-
const propNames = new Set(properties.map((x) => x.key.name));
-
const decl = properties.map((prop) => {
-
const key = `${id}$${prop.key.name}`;
-
return t.variableDeclarator(t.identifier(key), prop.value);
-
});
-
-
this.props.set(id, propNames);
-
path.parentPath.replaceWithMultiple(t.variableDeclaration('let', decl));
-
}
-
},
-
MemberExpression(path) {
-
if (
-
t.isIdentifier(path.node.object) &&
-
this.props.has(path.node.object.name) &&
-
t.isIdentifier(path.node.property) &&
-
this.props.get(path.node.object.name).has(path.node.property.name)
-
) {
-
const id = path.node.object.name;
-
const propName = path.node.property.name;
-
path.replaceWith(t.identifier(`${id}$${propName}`));
-
}
-
},
-
},
-
});
-
-
const curryGuaranteePlugin = ({ types: t }) => {
-
const curryFnName = /^_(\d)$/;
-
const lengthId = t.identifier('length');
-
const bindId = t.identifier('bind');
-
-
return {
-
visitor: {
-
CallExpression(path) {
-
if (
-
!t.isMemberExpression(path.node.callee) ||
-
!t.isIdentifier(path.node.callee.object) ||
-
!t.isIdentifier(path.node.callee.property) ||
-
!path.node.callee.object.name === 'Curry' ||
-
!curryFnName.test(path.node.callee.property.name)
-
)
-
return;
-
-
const callFn = path.node.arguments[0];
-
const callArgs = path.node.arguments.slice(1);
-
if (t.isExpressionStatement(path.parent)) {
-
path.replaceWith(t.callExpression(callFn, callArgs));
-
return;
-
}
-
-
const arityLiteral = t.numericLiteral(callArgs.length);
-
const argIds = callArgs.map((init) => {
-
if (t.isIdentifier(init)) return init;
-
const id = path.scope.generateUidIdentifierBasedOnNode(path.node.id);
-
path.scope.push({ id, init });
-
return id;
-
});
-
-
path.replaceWith(
-
t.conditionalExpression(
-
t.binaryExpression('===', t.memberExpression(callFn, lengthId), arityLiteral),
-
t.callExpression(callFn, argIds),
-
t.callExpression(t.memberExpression(callFn, bindId), [t.nullLiteral()].concat(argIds))
-
)
-
);
-
},
-
},
-
};
-
};
-
const makePlugins = (isProduction) =>
[
babel({
···
extensions: ['ts', 'tsx', 'js'],
exclude: 'node_modules/**',
presets: [],
-
plugins: ['babel-plugin-closure-elimination', unwrapStatePlugin, curryGuaranteePlugin],
}),
compiler({
formatting: 'PRETTY_PRINT',
compilation_level: 'SIMPLE_OPTIMIZATIONS',
···
import { terser } from 'rollup-plugin-terser';
import compiler from '@ampproject/rollup-plugin-closure-compiler';
+
import minifyBucklescript from './scripts/minify-bucklescript-plugin';
+
const cwd = process.cwd();
const pkgInfo = require('./package.json');
const name = basename(pkgInfo.main, '.js');
···
},
});
const makePlugins = (isProduction) =>
[
babel({
···
extensions: ['ts', 'tsx', 'js'],
exclude: 'node_modules/**',
presets: [],
+
plugins: ['babel-plugin-closure-elimination'],
}),
+
minifyBucklescript(),
compiler({
formatting: 'PRETTY_PRINT',
compilation_level: 'SIMPLE_OPTIMIZATIONS',
+122
scripts/minify-bucklescript-plugin.js
···
···
+
import { transformSync as transform } from '@babel/core';
+
import { createFilter } from 'rollup-pluginutils';
+
+
function unwrapStatePlugin({ types: t }) {
+
return {
+
pre() {
+
this.props = new Map();
+
this.test = (node) =>
+
/state$/i.test(node.id.name) ||
+
(node.init.properties.length === 1 && node.init.properties[0].key.name === 'contents');
+
},
+
visitor: {
+
VariableDeclarator(path) {
+
if (
+
t.isIdentifier(path.node.id) &&
+
t.isObjectExpression(path.node.init) &&
+
path.node.init.properties.every(
+
(prop) => t.isObjectProperty(prop) && t.isIdentifier(prop.key)
+
) &&
+
this.test(path.node)
+
) {
+
const id = path.node.id.name;
+
const properties = path.node.init.properties;
+
const propNames = new Set(properties.map((x) => x.key.name));
+
const decl = properties.map((prop) => {
+
const key = `${id}$${prop.key.name}`;
+
return t.variableDeclarator(t.identifier(key), prop.value);
+
});
+
+
this.props.set(id, propNames);
+
path.parentPath.replaceWithMultiple(t.variableDeclaration('let', decl));
+
}
+
},
+
MemberExpression(path) {
+
if (
+
t.isIdentifier(path.node.object) &&
+
this.props.has(path.node.object.name) &&
+
t.isIdentifier(path.node.property) &&
+
this.props.get(path.node.object.name).has(path.node.property.name)
+
) {
+
const id = path.node.object.name;
+
const propName = path.node.property.name;
+
path.replaceWith(t.identifier(`${id}$${propName}`));
+
}
+
},
+
},
+
};
+
}
+
+
function curryGuaranteePlugin({ types: t }) {
+
const curryFnName = /^_(\d)$/;
+
const lengthId = t.identifier('length');
+
const bindId = t.identifier('bind');
+
+
return {
+
visitor: {
+
CallExpression(path) {
+
if (!t.isIdentifier(path.node.callee) || !curryFnName.test(path.node.callee.name)) {
+
return;
+
}
+
+
const callFn = path.node.arguments[0];
+
const callArgs = path.node.arguments.slice(1);
+
+
if (t.isExpressionStatement(path.parent)) {
+
path.replaceWith(t.callExpression(callFn, callArgs));
+
return;
+
}
+
+
if (t.isIdentifier(callFn) && path.scope.hasBinding(callFn.name)) {
+
const callFnDefinition = path.scope.getBinding(callFn.name).path.node;
+
if (
+
t.isFunctionDeclaration(callFnDefinition) &&
+
callFnDefinition.params.length === callArgs.length
+
) {
+
path.replaceWith(t.callExpression(callFn, callArgs));
+
return;
+
}
+
}
+
+
const arityLiteral = t.numericLiteral(callArgs.length);
+
const argIds = callArgs.map((init) => {
+
if (t.isIdentifier(init)) return init;
+
const id = path.scope.generateUidIdentifierBasedOnNode(path.node.id);
+
path.scope.push({ id, init });
+
return id;
+
});
+
+
path.replaceWith(
+
t.conditionalExpression(
+
t.binaryExpression('===', t.memberExpression(callFn, lengthId), arityLiteral),
+
t.callExpression(callFn, argIds),
+
t.callExpression(t.memberExpression(callFn, bindId), [t.nullLiteral()].concat(argIds))
+
)
+
);
+
},
+
},
+
};
+
}
+
+
function cleanup(opts = {}) {
+
const filter = createFilter(opts.include, opts.exclude, {
+
resolve: false,
+
});
+
+
return {
+
name: 'minifyBucklescript',
+
+
renderChunk(code, chunk) {
+
if (!filter(chunk.fileName)) {
+
return null;
+
}
+
+
return transform(code, {
+
plugins: [unwrapStatePlugin, curryGuaranteePlugin],
+
babelrc: false,
+
});
+
},
+
};
+
}
+
+
export default cleanup;