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

Configure Feed

Select the types of activity you want to include in your feed.

Move bs-platform minification to chunk plugin

+126 -89
+4 -89
rollup.config.js
··· 7 7 import { terser } from 'rollup-plugin-terser'; 8 8 import compiler from '@ampproject/rollup-plugin-closure-compiler'; 9 9 10 + import minifyBucklescript from './scripts/minify-bucklescript-plugin'; 11 + 10 12 const cwd = process.cwd(); 11 13 const pkgInfo = require('./package.json'); 12 14 const name = basename(pkgInfo.main, '.js'); ··· 76 78 }, 77 79 }); 78 80 79 - const unwrapStatePlugin = ({ types: t }) => ({ 80 - pre() { 81 - this.props = new Map(); 82 - this.test = (node) => 83 - /state$/i.test(node.id.name) || 84 - (node.init.properties.length === 1 && node.init.properties[0].key.name === 'contents'); 85 - }, 86 - visitor: { 87 - VariableDeclarator(path) { 88 - if ( 89 - t.isIdentifier(path.node.id) && 90 - t.isObjectExpression(path.node.init) && 91 - path.node.init.properties.every( 92 - (prop) => t.isObjectProperty(prop) && t.isIdentifier(prop.key) 93 - ) && 94 - this.test(path.node) 95 - ) { 96 - const id = path.node.id.name; 97 - const properties = path.node.init.properties; 98 - const propNames = new Set(properties.map((x) => x.key.name)); 99 - const decl = properties.map((prop) => { 100 - const key = `${id}$${prop.key.name}`; 101 - return t.variableDeclarator(t.identifier(key), prop.value); 102 - }); 103 - 104 - this.props.set(id, propNames); 105 - path.parentPath.replaceWithMultiple(t.variableDeclaration('let', decl)); 106 - } 107 - }, 108 - MemberExpression(path) { 109 - if ( 110 - t.isIdentifier(path.node.object) && 111 - this.props.has(path.node.object.name) && 112 - t.isIdentifier(path.node.property) && 113 - this.props.get(path.node.object.name).has(path.node.property.name) 114 - ) { 115 - const id = path.node.object.name; 116 - const propName = path.node.property.name; 117 - path.replaceWith(t.identifier(`${id}$${propName}`)); 118 - } 119 - }, 120 - }, 121 - }); 122 - 123 - const curryGuaranteePlugin = ({ types: t }) => { 124 - const curryFnName = /^_(\d)$/; 125 - const lengthId = t.identifier('length'); 126 - const bindId = t.identifier('bind'); 127 - 128 - return { 129 - visitor: { 130 - CallExpression(path) { 131 - if ( 132 - !t.isMemberExpression(path.node.callee) || 133 - !t.isIdentifier(path.node.callee.object) || 134 - !t.isIdentifier(path.node.callee.property) || 135 - !path.node.callee.object.name === 'Curry' || 136 - !curryFnName.test(path.node.callee.property.name) 137 - ) 138 - return; 139 - 140 - const callFn = path.node.arguments[0]; 141 - const callArgs = path.node.arguments.slice(1); 142 - if (t.isExpressionStatement(path.parent)) { 143 - path.replaceWith(t.callExpression(callFn, callArgs)); 144 - return; 145 - } 146 - 147 - const arityLiteral = t.numericLiteral(callArgs.length); 148 - const argIds = callArgs.map((init) => { 149 - if (t.isIdentifier(init)) return init; 150 - const id = path.scope.generateUidIdentifierBasedOnNode(path.node.id); 151 - path.scope.push({ id, init }); 152 - return id; 153 - }); 154 - 155 - path.replaceWith( 156 - t.conditionalExpression( 157 - t.binaryExpression('===', t.memberExpression(callFn, lengthId), arityLiteral), 158 - t.callExpression(callFn, argIds), 159 - t.callExpression(t.memberExpression(callFn, bindId), [t.nullLiteral()].concat(argIds)) 160 - ) 161 - ); 162 - }, 163 - }, 164 - }; 165 - }; 166 - 167 81 const makePlugins = (isProduction) => 168 82 [ 169 83 babel({ ··· 213 127 extensions: ['ts', 'tsx', 'js'], 214 128 exclude: 'node_modules/**', 215 129 presets: [], 216 - plugins: ['babel-plugin-closure-elimination', unwrapStatePlugin, curryGuaranteePlugin], 130 + plugins: ['babel-plugin-closure-elimination'], 217 131 }), 132 + minifyBucklescript(), 218 133 compiler({ 219 134 formatting: 'PRETTY_PRINT', 220 135 compilation_level: 'SIMPLE_OPTIMIZATIONS',
+122
scripts/minify-bucklescript-plugin.js
··· 1 + import { transformSync as transform } from '@babel/core'; 2 + import { createFilter } from 'rollup-pluginutils'; 3 + 4 + function unwrapStatePlugin({ types: t }) { 5 + return { 6 + pre() { 7 + this.props = new Map(); 8 + this.test = (node) => 9 + /state$/i.test(node.id.name) || 10 + (node.init.properties.length === 1 && node.init.properties[0].key.name === 'contents'); 11 + }, 12 + visitor: { 13 + VariableDeclarator(path) { 14 + if ( 15 + t.isIdentifier(path.node.id) && 16 + t.isObjectExpression(path.node.init) && 17 + path.node.init.properties.every( 18 + (prop) => t.isObjectProperty(prop) && t.isIdentifier(prop.key) 19 + ) && 20 + this.test(path.node) 21 + ) { 22 + const id = path.node.id.name; 23 + const properties = path.node.init.properties; 24 + const propNames = new Set(properties.map((x) => x.key.name)); 25 + const decl = properties.map((prop) => { 26 + const key = `${id}$${prop.key.name}`; 27 + return t.variableDeclarator(t.identifier(key), prop.value); 28 + }); 29 + 30 + this.props.set(id, propNames); 31 + path.parentPath.replaceWithMultiple(t.variableDeclaration('let', decl)); 32 + } 33 + }, 34 + MemberExpression(path) { 35 + if ( 36 + t.isIdentifier(path.node.object) && 37 + this.props.has(path.node.object.name) && 38 + t.isIdentifier(path.node.property) && 39 + this.props.get(path.node.object.name).has(path.node.property.name) 40 + ) { 41 + const id = path.node.object.name; 42 + const propName = path.node.property.name; 43 + path.replaceWith(t.identifier(`${id}$${propName}`)); 44 + } 45 + }, 46 + }, 47 + }; 48 + } 49 + 50 + function curryGuaranteePlugin({ types: t }) { 51 + const curryFnName = /^_(\d)$/; 52 + const lengthId = t.identifier('length'); 53 + const bindId = t.identifier('bind'); 54 + 55 + return { 56 + visitor: { 57 + CallExpression(path) { 58 + if (!t.isIdentifier(path.node.callee) || !curryFnName.test(path.node.callee.name)) { 59 + return; 60 + } 61 + 62 + const callFn = path.node.arguments[0]; 63 + const callArgs = path.node.arguments.slice(1); 64 + 65 + if (t.isExpressionStatement(path.parent)) { 66 + path.replaceWith(t.callExpression(callFn, callArgs)); 67 + return; 68 + } 69 + 70 + if (t.isIdentifier(callFn) && path.scope.hasBinding(callFn.name)) { 71 + const callFnDefinition = path.scope.getBinding(callFn.name).path.node; 72 + if ( 73 + t.isFunctionDeclaration(callFnDefinition) && 74 + callFnDefinition.params.length === callArgs.length 75 + ) { 76 + path.replaceWith(t.callExpression(callFn, callArgs)); 77 + return; 78 + } 79 + } 80 + 81 + const arityLiteral = t.numericLiteral(callArgs.length); 82 + const argIds = callArgs.map((init) => { 83 + if (t.isIdentifier(init)) return init; 84 + const id = path.scope.generateUidIdentifierBasedOnNode(path.node.id); 85 + path.scope.push({ id, init }); 86 + return id; 87 + }); 88 + 89 + path.replaceWith( 90 + t.conditionalExpression( 91 + t.binaryExpression('===', t.memberExpression(callFn, lengthId), arityLiteral), 92 + t.callExpression(callFn, argIds), 93 + t.callExpression(t.memberExpression(callFn, bindId), [t.nullLiteral()].concat(argIds)) 94 + ) 95 + ); 96 + }, 97 + }, 98 + }; 99 + } 100 + 101 + function cleanup(opts = {}) { 102 + const filter = createFilter(opts.include, opts.exclude, { 103 + resolve: false, 104 + }); 105 + 106 + return { 107 + name: 'minifyBucklescript', 108 + 109 + renderChunk(code, chunk) { 110 + if (!filter(chunk.fileName)) { 111 + return null; 112 + } 113 + 114 + return transform(code, { 115 + plugins: [unwrapStatePlugin, curryGuaranteePlugin], 116 + babelrc: false, 117 + }); 118 + }, 119 + }; 120 + } 121 + 122 + export default cleanup;