Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: lukeed/obj-str
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.3
Choose a base ref
...
head repository: lukeed/obj-str
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.1.0
Choose a head ref
  • 16 commits
  • 35 files changed
  • 3 contributors

Commits on Feb 18, 2021

  1. feat: add babel-plugin-optimize-obj-str package (#6)

    * babel-plugin-optimize-obj-str
    
    * readme: Output Code Performance
    
    * Wording
    
    * consistent tables
    
    * Wording again (sorry)
    
    * section
    
    * Remove leadingSpace option: always includes leading space
    
    * Update babel-plugin-optimize-obj-str/src/index.js
    
    Co-authored-by: Luke Edwards <luke.edwards05@gmail.com>
    
    * Remove referencesImport option
    
    * Evaluate static
    
    * function ()
    
    * Update readme now that expressions are evald
    
    * Restore test for quoted key
    
    Co-authored-by: Luke Edwards <luke.edwards05@gmail.com>
    alanorozco and lukeed authored Feb 18, 2021

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    3e8c367 View commit details
  2. chore: update pkg meta

    lukeed committed Feb 18, 2021

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    06a3b68 View commit details
  3. chore: update test runner

    lukeed committed Feb 18, 2021

    Verified

    This commit was signed with the committer’s verified signature.
    stefanprodan Stefan Prodan
    Copy the full SHA
    56b9c4f View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    248fc3d View commit details
  5. chore(babel): remove "src" dir

    lukeed committed Feb 18, 2021

    Verified

    This commit was signed with the committer’s verified signature.
    stefanprodan Stefan Prodan
    Copy the full SHA
    6cd8fde View commit details
  6. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6042e48 View commit details
  7. Verified

    This commit was signed with the committer’s verified signature.
    stefanprodan Stefan Prodan
    Copy the full SHA
    d41cc92 View commit details
  8. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c85eb79 View commit details
  9. Copy the full SHA
    72f31a6 View commit details
  10. Copy the full SHA
    9a8f195 View commit details
  11. Copy the full SHA
    08c6d8f View commit details
  12. chore: update badges

    lukeed committed Feb 18, 2021
    Copy the full SHA
    b84395e View commit details

Commits on Feb 24, 2021

  1. Copy the full SHA
    b510216 View commit details

Commits on Mar 26, 2021

  1. Copy the full SHA
    ccbfdbc View commit details

Commits on Mar 27, 2021

  1. feat: add type definitions;

    - Closes #11
    lukeed committed Mar 27, 2021
    Copy the full SHA
    99bfb32 View commit details
  2. 1.1.0

    lukeed committed Mar 27, 2021
    Copy the full SHA
    0b3e060 View commit details
Showing with 662 additions and 29 deletions.
  1. +1 −0 .github/FUNDING.yml
  2. +45 −0 .github/workflows/ci.yml
  3. +1 −0 .gitignore
  4. +0 −3 .travis.yml
  5. +139 −0 babel-plugin-optimize-obj-str/index.js
  6. +31 −0 babel-plugin-optimize-obj-str/package.json
  7. +171 −0 babel-plugin-optimize-obj-str/readme.md
  8. +1 −0 index.d.ts
  9. +9 −7 package.json
  10. +4 −2 readme.md
  11. +39 −0 test/babel.js
  12. +22 −0 test/fixtures/dedupe-properties/input.mjs
  13. +3 −0 test/fixtures/dedupe-properties/options.json
  14. +4 −0 test/fixtures/dedupe-properties/output.mjs
  15. +1 −0 test/fixtures/ignore-no-import/input.mjs
  16. +3 −0 test/fixtures/ignore-no-import/options.json
  17. +3 −0 test/fixtures/ignore-no-import/output.mjs
  18. +12 −0 test/fixtures/ignore-unoptimizable/input.mjs
  19. +3 −0 test/fixtures/ignore-unoptimizable/options.json
  20. +19 −0 test/fixtures/ignore-unoptimizable/output.mjs
  21. +24 −0 test/fixtures/optimize/input.mjs
  22. +3 −0 test/fixtures/optimize/options.json
  23. +10 −0 test/fixtures/optimize/output.mjs
  24. +3 −0 test/fixtures/strict-ok/input.mjs
  25. +4 −0 test/fixtures/strict-ok/options.json
  26. +2 −0 test/fixtures/strict-ok/output.mjs
  27. +3 −0 test/fixtures/strict-throw-arg/input.mjs
  28. +4 −0 test/fixtures/strict-throw-arg/options.json
  29. +6 −0 test/fixtures/strict-throw-multiple-args/input.mjs
  30. +4 −0 test/fixtures/strict-throw-multiple-args/options.json
  31. +4 −0 test/fixtures/strict-throw-no-arg/input.mjs
  32. +4 −0 test/fixtures/strict-throw-no-arg/options.json
  33. +6 −0 test/fixtures/strict-throw-property/input.mjs
  34. +4 −0 test/fixtures/strict-throw-property/options.json
  35. +70 −17 test/index.js
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: lukeed
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI

on: [push, pull_request]

jobs:
test:
name: Node.js v${{ matrix.nodejs }}
runs-on: ubuntu-latest
strategy:
matrix:
nodejs: [8, 10, 12]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.nodejs }}

- name: (cache) restore
uses: actions/cache@master
with:
path: node_modules
key: ${{ runner.os }}-${{ hashFiles('**/package.json') }}

- name: Install
run: npm install

- name: (coverage) Install
if: matrix.nodejs >= 12
run: npm install -g nyc

- name: Test
run: npm test
if: matrix.nodejs < 12

- name: (coverage) Test
run: nyc --include=src --include=babel-plugin-optimize-obj-str npm test
if: matrix.nodejs >= 12

- name: (coverage) Report
if: matrix.nodejs >= 12
run: |
nyc report --reporter=text-lcov > coverage.lcov
bash <(curl -s https://codecov.io/bash)
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules
.DS_Store
*-lock.*
*.lock
*.log

3 changes: 0 additions & 3 deletions .travis.yml

This file was deleted.

139 changes: 139 additions & 0 deletions babel-plugin-optimize-obj-str/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// @ts-check

/**
* @typedef {import('@babel/core').Node} Node
* @typedef {import('@babel/core').NodePath<*>} NodePath
* @typedef {import('@babel/core').PluginItem} PluginItem
* @typedef {import('@babel/core').types.ObjectExpression['properties']} ObjectProperties
*/

/**
* @param {import('@babel/core')} babel
* @param {object} [options]
* @param {boolean} [options.strict]
* @returns {PluginItem}
*/
module.exports = function (babel, options={}) {
const { types: t } = babel;
const { ast } = babel.template.expression;

/**
* Fails on strict mode when encountering an unoptimizable case.
* @param {NodePath} path
* @param {string} message
*/
function unoptimizable(path, message) {
if (options.strict) throw path.buildCodeFrameError(`${path.node.callee.name}() ` + message);
}

/**
* Decontextualizes a node for comparison with a different node, irrespective
* of its location in source or surrounding comments.
* @param {Node} node
*/
function decontextualize(node) {
const clean = { ...node };
delete clean.extra;
delete clean.loc;
delete clean.start;
delete clean.end;
delete clean.range;
delete clean.innerComments;
delete clean.trailingComments;
delete clean.leadingComments;
for (const k in clean) {
if (clean[k] && clean[k].type) {
clean[k] = decontextualize(clean[k]);
}
}
return clean;
}

/**
* Converts identifier property keys into string literals as mapped by spec,
* as how {a: x} is the same as {'a': x}.
* @NOTE Ignores `SpreadElement` intentionally; see `dedupe`
* @param {ObjectProperties[number]} prop
*/
function propKey(prop) {
return t.isSpreadElement(prop) ? void 0 :
t.isIdentifier(prop.key) && !prop.computed
? t.stringLiteral(prop.key.name)
: prop.key;
}

/**
* Removes properties with duplicate keys, honoring the lastly defined value.
* @param {NodePath} path
* @param {ObjectProperties} properties
* @returns {ObjectProperties|void}
*/
function dedupe(path, properties) {
const cache = Object.create(null);
for (let prop of properties) {
if ('key' in prop) {
cache[JSON.stringify(decontextualize(propKey(prop)))] = prop;
} else {
let { type, argument } = prop;
return unoptimizable(path, `must only contain keyed props, found [${type}] ${
(argument && argument.name) || '(unknown)'
}`);
}
}
return Object.values(cache);
}

/**
* Replaces a path with a simpler constant value if possible.
* @param {NodePath} path
*/
function tryEval(path) {
const { confident, value } = path.evaluate();
if (confident) path.replaceWith(ast(JSON.stringify(value)));
}

/**
* Generates expression to concatenate strings.
* @param {ObjectProperties} properties
*/
function expr(properties) {
return properties.reduce((previous, prop) => {
const condition = prop.value;
const part = propKey(prop);
return previous
? ast`${previous} + (${condition} ? ' ' + ${part} : '')`
: ast`'' + (${condition} ? ${part} : '')`;
}, null);
}

return {
name: 'optimize-obj-str',
visitor: {
CallExpression(path) {
const callee = path.get('callee');
if (!callee.referencesImport('obj-str', 'default')) return;

const argument = path.node.arguments[0];
if (path.node.arguments.length !== 1 || !t.isObjectExpression(argument)) {
return unoptimizable(path, 'argument should be a single Object Expression initializer.');
}

const properties = dedupe(path, argument.properties);

if (properties) {
path.replaceWith(
expr(properties)
);

path.traverse({
BinaryExpression: tryEval,
ConditionalExpression: tryEval,
LogicalExpression: tryEval,
});

tryEval(path);
}
}
}
};
};
31 changes: 31 additions & 0 deletions babel-plugin-optimize-obj-str/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"version": "1.0.0",
"name": "babel-plugin-optimize-objstr",
"description": "Babel plugin to optimize `obj-str` calls.",
"repository": "lukeed/obj-str",
"license": "MIT",
"author": {
"name": "Luke Edwards",
"email": "luke.edwards05@gmail.com",
"url": "https://lukeed.com"
},
"contributors": [{
"name": "Alan Orozco",
"email": "alan@orozco.xyz",
"url": "https://alanoroz.co"
}],
"keywords": [
"babel",
"optimize",
"react",
"preact",
"classes",
"classname",
"classnames",
"object",
"object-keys",
"object-string",
"object-values",
"serialize"
]
}
Loading