Skip to content

Commit

Permalink
fix: summarize tokens before embedding dictionaries (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
gjbkz committed Sep 20, 2019
1 parent c3ab926 commit 6dc5f06
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 27 deletions.
61 changes: 55 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
},
"dependencies": {
"@nlib/afs": "^3.13.3",
"esifycss": "^1.3.5",
"esifycss": "^1.3.6",
"postcss": "^7.0.18",
"rollup-pluginutils": "^2.8.2"
},
Expand Down Expand Up @@ -100,7 +100,8 @@
"test/util.ts"
],
"rules": {
"class-methods-use-this": "off"
"class-methods-use-this": "off",
"@typescript-eslint/no-explicit-any": "off"
}
}
]
Expand Down
5 changes: 5 additions & 0 deletions src/isOutputChunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as rollup from 'rollup';

export const isOutputChunk = (
x: rollup.OutputAsset | rollup.OutputChunk,
): x is rollup.OutputChunk => 'code' in x;
33 changes: 20 additions & 13 deletions src/updateBundle.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
import * as esifycss from 'esifycss';
import * as rollup from 'rollup';
import {isOutputChunk} from './isOutputChunk';

export const updateBundle = (
bundle: rollup.OutputBundle,
): void => {
for (const [, chunk] of Object.entries(bundle)) {
let {code} = chunk;
if (code) {
const cssRanges = esifycss.extractCSSFromScript(code);
const tokens = new Map<string, number>();
for (const rule of cssRanges) {
for (const token of esifycss.tokenizeString(rule.css)) {
tokens.set(token, (tokens.get(token) || 0) + 1);
}
const tokens = new Map<string, number>();
const chunks = Object.values(bundle)
.filter(isOutputChunk)
.map((chunk) => {
const cssRanges = esifycss.extractCSSFromScript(chunk.code);
const tokens = new Map<string, number>();
for (const rule of cssRanges) {
for (const token of esifycss.tokenizeString(rule.css)) {
tokens.set(token, (tokens.get(token) || 0) + 1);
}
const identifier = esifycss.createOptimizedIdentifier(tokens);
code = esifycss.minifyCSSInScript(code, cssRanges, identifier);
code = esifycss.setDictionary(code, identifier.idList);
chunk.code = code;
}
return {
chunk,
cssRanges,
};
});
const identifier = esifycss.createOptimizedIdentifier(tokens);
for (const {chunk, cssRanges} of chunks) {
let code = esifycss.minifyCSSInScript(chunk.code, cssRanges, identifier);
code = esifycss.setDictionary(code, identifier.idList);
chunk.code = code;
}
};
3 changes: 3 additions & 0 deletions test/simple/b.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.bar {
color: red;
}
1 change: 1 addition & 0 deletions test/simple/input.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import './b.css';
import * as a from './a.css';
export const result = a;
11 changes: 6 additions & 5 deletions test/simple/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@ test(path.basename(__dirname), async (t) => {
const sandbox = createSandbox<{
result: esifycss.IEsifyCSSResult,
}>();
vm.runInNewContext(output[0].code, sandbox);
const script = output[0].code;
vm.runInNewContext(script, sandbox);
const css = [...sandbox.document.stylesheets].map((sheet) => {
return [...sheet.cssRules].map((rule) => rule.cssText).join('');
}).join('');
const root = postcss.parse(css);
const nodes = root.nodes || [];
const result = sandbox.exports.result || {id: {}, className: {}, keyframes: {}};
t.is(nodes.length, 3);
t.is(nodes.length, 4);
{
const node = nodes[0] as postcss.AtRule;
const node = nodes[1] as postcss.AtRule;
t.is(node.type, 'atrule');
t.is(node.name, 'keyframes');
t.is(node.params, result.keyframes.foo);
}
{
const node = nodes[1] as postcss.Rule;
const node = nodes[2] as postcss.Rule;
t.is(node.type, 'rule');
t.is(node.selector, `#${result.id.foo}`);
const declarations = (node.nodes || []) as Array<postcss.Declaration>;
Expand All @@ -45,7 +46,7 @@ test(path.basename(__dirname), async (t) => {
);
}
{
const node = nodes[2] as postcss.Rule;
const node = nodes[3] as postcss.Rule;
t.is(node.type, 'rule');
t.is(node.selector, `.${result.className.foo}`);
const declarations = (node.nodes || []) as Array<postcss.Declaration>;
Expand Down
26 changes: 25 additions & 1 deletion test/util.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
class Console {

public readonly data: Array<any>;

public constructor() {
this.data = [];
}

public log(...args: Array<any>): void {
this.data.push(args);
}
}
const console = new Console();

class Element {

public readonly tagName: string;
Expand All @@ -10,6 +24,10 @@ class Element {
}

public appendChild(element: Element) {
const index = this.children.indexOf(element);
if (0 <= index) {
this.children.splice(index, 1);
}
this.children.push(element);
}

Expand All @@ -34,7 +52,11 @@ class StyleSheet {
}

public insertRule(cssText: string, index = 0) {
this.cssRules.splice(index, 0, new CSSRule(cssText));
if (cssText.trim()) {
this.cssRules.splice(index, 0, new CSSRule(cssText));
} else {
throw new Error('DOMException: Failed to execute \'insertRule\' on \'CSSStyleSheet\': Failed to parse the rule \'\'');
}
}

}
Expand Down Expand Up @@ -102,10 +124,12 @@ class Document {

export interface ISandbox<TExports extends {}> {
document: Document,
console: Console,
exports: Partial<TExports>,
}

export const createSandbox = <TExports extends {}>(): ISandbox<TExports> => ({
document: new Document(),
console,
exports: {},
});

0 comments on commit 6dc5f06

Please sign in to comment.