From 4260ffd7eca25d3ab75482eab3610b18c35e470c Mon Sep 17 00:00:00 2001 From: Dennis Czombera Date: Thu, 10 May 2018 20:54:10 +0200 Subject: [PATCH] Lazy load tagged template literal strings (#7855) * Lazy load tagged template literal strings * Update snapshots to reflect lazy loading * Use pure annotation and remove unnecessary parenthesized expression * Update snapshots * Optimize lazy loading by doing assignment within logical expression * Update snapshots to reflect optimization * Use re-define function pattern to avoid hitting function size deopts * Update snapshots to reflect the usage of the redefining function pattern --- .../interop-loose/imports-hoisting/output.js | 12 +- .../interop/imports-hoisting/output.js | 12 +- .../src/index.js | 25 +++-- .../fixtures/default/cache-revision/output.js | 25 ++++- .../fixtures/default/simple-tag/output.js | 25 ++++- .../test/fixtures/default/tag/output.js | 38 ++++++- .../default/template-revision/output.js | 103 +++++++++++++++--- .../test/fixtures/loose/tag/output.js | 38 ++++++- .../loose/template-revision/output.js | 103 +++++++++++++++--- 9 files changed, 314 insertions(+), 67 deletions(-) diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/imports-hoisting/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/imports-hoisting/output.js index f3ae7f0971..df902a7c8f 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/imports-hoisting/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/imports-hoisting/output.js @@ -4,6 +4,14 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); -var _templateObject = /*#__PURE__*/ (0, _taggedTemplateLiteral2.default)(["foo"]); +function _templateObject() { + const data = /*#__PURE__*/ (0, _taggedTemplateLiteral2.default)(["foo"]); -tag(_templateObject); + _templateObject = function () { + return data; + }; + + return data; +} + +tag(_templateObject()); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/imports-hoisting/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/imports-hoisting/output.js index f3ae7f0971..df902a7c8f 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/imports-hoisting/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/imports-hoisting/output.js @@ -4,6 +4,14 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau var _taggedTemplateLiteral2 = _interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral")); -var _templateObject = /*#__PURE__*/ (0, _taggedTemplateLiteral2.default)(["foo"]); +function _templateObject() { + const data = /*#__PURE__*/ (0, _taggedTemplateLiteral2.default)(["foo"]); -tag(_templateObject); + _templateObject = function () { + return data; + }; + + return data; +} + +tag(_templateObject()); diff --git a/packages/babel-plugin-transform-template-literals/src/index.js b/packages/babel-plugin-transform-template-literals/src/index.js index 39f201f833..3373b02042 100644 --- a/packages/babel-plugin-transform-template-literals/src/index.js +++ b/packages/babel-plugin-transform-template-literals/src/index.js @@ -1,6 +1,6 @@ import { declare } from "@babel/helper-plugin-utils"; import annotateAsPure from "@babel/helper-annotate-as-pure"; -import { types as t } from "@babel/core"; +import { template, types as t } from "@babel/core"; export default declare((api, options) => { api.assertVersion(7); @@ -83,19 +83,22 @@ export default declare((api, options) => { callExpressionInput.push(t.arrayExpression(raws)); } - const init = t.callExpression(helperId, callExpressionInput); - annotateAsPure(init); - init._compact = true; - scope.push({ - id: templateObject, - init, - // This ensures that we don't fail if not using function expression helpers - _blockHoist: 1.9, - }); + const callExpression = t.callExpression(helperId, callExpressionInput); + annotateAsPure(callExpression); + callExpression._compact = true; + const lazyLoad = template.ast` + function ${templateObject}() { + const data = ${callExpression}; + ${templateObject} = function() { return data }; + return data; + } + `; + + scope.path.unshiftContainer("body", lazyLoad); path.replaceWith( t.callExpression(node.tag, [ - t.cloneNode(templateObject), + t.callExpression(t.cloneNode(templateObject), []), ...quasi.expressions, ]), ); diff --git a/packages/babel-plugin-transform-template-literals/test/fixtures/default/cache-revision/output.js b/packages/babel-plugin-transform-template-literals/test/fixtures/default/cache-revision/output.js index 8a02e8fcba..7e41808f5f 100644 --- a/packages/babel-plugin-transform-template-literals/test/fixtures/default/cache-revision/output.js +++ b/packages/babel-plugin-transform-template-literals/test/fixtures/default/cache-revision/output.js @@ -1,16 +1,33 @@ -var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral(["some template"]), - _templateObject2 = /*#__PURE__*/ _taggedTemplateLiteral(["some template"]); +function _templateObject2() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["some template"]); + + _templateObject2 = function () { + return data; + }; + + return data; +} + +function _templateObject() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["some template"]); + + _templateObject = function () { + return data; + }; + + return data; +} function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } var tag = v => v; function foo() { - return tag(_templateObject); + return tag(_templateObject()); } function bar() { - return tag(_templateObject2); + return tag(_templateObject2()); } expect(foo()).toBe(foo()); diff --git a/packages/babel-plugin-transform-template-literals/test/fixtures/default/simple-tag/output.js b/packages/babel-plugin-transform-template-literals/test/fixtures/default/simple-tag/output.js index 7b916abd6b..87b40045d6 100644 --- a/packages/babel-plugin-transform-template-literals/test/fixtures/default/simple-tag/output.js +++ b/packages/babel-plugin-transform-template-literals/test/fixtures/default/simple-tag/output.js @@ -1,7 +1,24 @@ -var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral(["wow"]), - _templateObject2 = /*#__PURE__*/ _taggedTemplateLiteral(["first", "second"]); +function _templateObject2() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["first", "second"]); + + _templateObject2 = function () { + return data; + }; + + return data; +} + +function _templateObject() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["wow"]); + + _templateObject = function () { + return data; + }; + + return data; +} function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } -var foo = tag(_templateObject); -var bar = tag(_templateObject2, 1); +var foo = tag(_templateObject()); +var bar = tag(_templateObject2(), 1); diff --git a/packages/babel-plugin-transform-template-literals/test/fixtures/default/tag/output.js b/packages/babel-plugin-transform-template-literals/test/fixtures/default/tag/output.js index b47badfa7f..6a37348dda 100644 --- a/packages/babel-plugin-transform-template-literals/test/fixtures/default/tag/output.js +++ b/packages/babel-plugin-transform-template-literals/test/fixtures/default/tag/output.js @@ -1,9 +1,35 @@ -var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), - _templateObject2 = /*#__PURE__*/ _taggedTemplateLiteral(["wow\nab", " ", ""], ["wow\\nab", " ", ""]), - _templateObject3 = /*#__PURE__*/ _taggedTemplateLiteral(["wow\naB", " ", ""], ["wow\\naB", " ", ""]); +function _templateObject3() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["wow\naB", " ", ""], ["wow\\naB", " ", ""]); + + _templateObject3 = function () { + return data; + }; + + return data; +} + +function _templateObject2() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["wow\nab", " ", ""], ["wow\\nab", " ", ""]); + + _templateObject2 = function () { + return data; + }; + + return data; +} + +function _templateObject() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]); + + _templateObject = function () { + return data; + }; + + return data; +} function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } -var foo = bar(_templateObject, 42, _.foobar()); -var bar = bar(_templateObject2, 42, _.foobar()); -var bar = bar(_templateObject3, 42, _.baz()); +var foo = bar(_templateObject(), 42, _.foobar()); +var bar = bar(_templateObject2(), 42, _.foobar()); +var bar = bar(_templateObject3(), 42, _.baz()); diff --git a/packages/babel-plugin-transform-template-literals/test/fixtures/default/template-revision/output.js b/packages/babel-plugin-transform-template-literals/test/fixtures/default/template-revision/output.js index 2a4f3bff53..87294b20a3 100644 --- a/packages/babel-plugin-transform-template-literals/test/fixtures/default/template-revision/output.js +++ b/packages/babel-plugin-transform-template-literals/test/fixtures/default/template-revision/output.js @@ -1,23 +1,94 @@ -var _templateObject = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\unicode and \\u{55}"]), - _templateObject2 = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\01"]), - _templateObject3 = /*#__PURE__*/ _taggedTemplateLiteral([void 0, "right"], ["\\xg", "right"]), - _templateObject4 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0], ["left", "\\xg"]), - _templateObject5 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\xg", "right"]), - _templateObject6 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u000g", "right"]), - _templateObject7 = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u{-0}", "right"]), - _templateObject8 = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\01"]); +function _templateObject8() { + const data = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\01"]); + + _templateObject8 = function () { + return data; + }; + + return data; +} + +function _templateObject7() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u{-0}", "right"]); + + _templateObject7 = function () { + return data; + }; + + return data; +} + +function _templateObject6() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\u000g", "right"]); + + _templateObject6 = function () { + return data; + }; + + return data; +} + +function _templateObject5() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0, "right"], ["left", "\\xg", "right"]); + + _templateObject5 = function () { + return data; + }; + + return data; +} + +function _templateObject4() { + const data = /*#__PURE__*/ _taggedTemplateLiteral(["left", void 0], ["left", "\\xg"]); + + _templateObject4 = function () { + return data; + }; + + return data; +} + +function _templateObject3() { + const data = /*#__PURE__*/ _taggedTemplateLiteral([void 0, "right"], ["\\xg", "right"]); + + _templateObject3 = function () { + return data; + }; + + return data; +} + +function _templateObject2() { + const data = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\01"]); + + _templateObject2 = function () { + return data; + }; + + return data; +} + +function _templateObject() { + const data = /*#__PURE__*/ _taggedTemplateLiteral([void 0], ["\\unicode and \\u{55}"]); + + _templateObject = function () { + return data; + }; + + return data; +} function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } -tag(_templateObject); -tag(_templateObject2); -tag(_templateObject3, 0); -tag(_templateObject4, 0); -tag(_templateObject5, 0, 1); -tag(_templateObject6, 0, 1); -tag(_templateObject7, 0, 1); +tag(_templateObject()); +tag(_templateObject2()); +tag(_templateObject3(), 0); +tag(_templateObject4(), 0); +tag(_templateObject5(), 0, 1); +tag(_templateObject6(), 0, 1); +tag(_templateObject7(), 0, 1); function a() { var undefined = 4; - tag(_templateObject8); + tag(_templateObject8()); } diff --git a/packages/babel-plugin-transform-template-literals/test/fixtures/loose/tag/output.js b/packages/babel-plugin-transform-template-literals/test/fixtures/loose/tag/output.js index 7e82908b36..6091fa15aa 100644 --- a/packages/babel-plugin-transform-template-literals/test/fixtures/loose/tag/output.js +++ b/packages/babel-plugin-transform-template-literals/test/fixtures/loose/tag/output.js @@ -1,9 +1,35 @@ -var _templateObject = /*#__PURE__*/ _taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), - _templateObject2 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["wow\nab", " ", ""], ["wow\\nab", " ", ""]), - _templateObject3 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["wow\naB", " ", ""], ["wow\\naB", " ", ""]); +function _templateObject3() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose(["wow\naB", " ", ""], ["wow\\naB", " ", ""]); + + _templateObject3 = function () { + return data; + }; + + return data; +} + +function _templateObject2() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose(["wow\nab", " ", ""], ["wow\\nab", " ", ""]); + + _templateObject2 = function () { + return data; + }; + + return data; +} + +function _templateObject() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]); + + _templateObject = function () { + return data; + }; + + return data; +} function _taggedTemplateLiteralLoose(strings, raw) { if (!raw) { raw = strings.slice(0); } strings.raw = raw; return strings; } -var foo = bar(_templateObject, 42, _.foobar()); -var bar = bar(_templateObject2, 42, _.foobar()); -var bar = bar(_templateObject3, 42, _.baz()); +var foo = bar(_templateObject(), 42, _.foobar()); +var bar = bar(_templateObject2(), 42, _.foobar()); +var bar = bar(_templateObject3(), 42, _.baz()); diff --git a/packages/babel-plugin-transform-template-literals/test/fixtures/loose/template-revision/output.js b/packages/babel-plugin-transform-template-literals/test/fixtures/loose/template-revision/output.js index 83ecc60448..bab93d9679 100644 --- a/packages/babel-plugin-transform-template-literals/test/fixtures/loose/template-revision/output.js +++ b/packages/babel-plugin-transform-template-literals/test/fixtures/loose/template-revision/output.js @@ -1,23 +1,94 @@ -var _templateObject = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\unicode and \\u{55}"]), - _templateObject2 = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\01"]), - _templateObject3 = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0, "right"], ["\\xg", "right"]), - _templateObject4 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0], ["left", "\\xg"]), - _templateObject5 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\xg", "right"]), - _templateObject6 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u000g", "right"]), - _templateObject7 = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u{-0}", "right"]), - _templateObject8 = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\01"]); +function _templateObject8() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\01"]); + + _templateObject8 = function () { + return data; + }; + + return data; +} + +function _templateObject7() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u{-0}", "right"]); + + _templateObject7 = function () { + return data; + }; + + return data; +} + +function _templateObject6() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\u000g", "right"]); + + _templateObject6 = function () { + return data; + }; + + return data; +} + +function _templateObject5() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0, "right"], ["left", "\\xg", "right"]); + + _templateObject5 = function () { + return data; + }; + + return data; +} + +function _templateObject4() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose(["left", void 0], ["left", "\\xg"]); + + _templateObject4 = function () { + return data; + }; + + return data; +} + +function _templateObject3() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0, "right"], ["\\xg", "right"]); + + _templateObject3 = function () { + return data; + }; + + return data; +} + +function _templateObject2() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\01"]); + + _templateObject2 = function () { + return data; + }; + + return data; +} + +function _templateObject() { + const data = /*#__PURE__*/ _taggedTemplateLiteralLoose([void 0], ["\\unicode and \\u{55}"]); + + _templateObject = function () { + return data; + }; + + return data; +} function _taggedTemplateLiteralLoose(strings, raw) { if (!raw) { raw = strings.slice(0); } strings.raw = raw; return strings; } -tag(_templateObject); -tag(_templateObject2); -tag(_templateObject3, 0); -tag(_templateObject4, 0); -tag(_templateObject5, 0, 1); -tag(_templateObject6, 0, 1); -tag(_templateObject7, 0, 1); +tag(_templateObject()); +tag(_templateObject2()); +tag(_templateObject3(), 0); +tag(_templateObject4(), 0); +tag(_templateObject5(), 0, 1); +tag(_templateObject6(), 0, 1); +tag(_templateObject7(), 0, 1); function a() { var undefined = 4; - tag(_templateObject8); + tag(_templateObject8()); }