vue-inbrowser-compiler
Advanced tools
Comparing version 4.44.24 to 4.50.0
# Change Log | ||
## 4.50.0 | ||
### Minor Changes | ||
- [`6308307b`](https://github.com/vue-styleguidist/vue-styleguidist/commit/6308307bc91cc215090dd9e33a3faf0af26427dc) Thanks [@elevatebart](https://github.com/elevatebart)! - remove the need for using a template compiling alias of vue | ||
### Patch Changes | ||
- Updated dependencies [[`6308307b`](https://github.com/vue-styleguidist/vue-styleguidist/commit/6308307bc91cc215090dd9e33a3faf0af26427dc)]: | ||
- vue-inbrowser-compiler-utils@4.50.0 | ||
## 4.45.0 | ||
### Minor Changes | ||
- [#1366](https://github.com/vue-styleguidist/vue-styleguidist/pull/1366) [`bbc09354`](https://github.com/vue-styleguidist/vue-styleguidist/commit/bbc09354ee9d23a368a449260d923dc7c034650c) Thanks [@elevatebart](https://github.com/elevatebart)! - remove the need for using a template compiling alias of vue | ||
### Patch Changes | ||
- Updated dependencies [[`bbc09354`](https://github.com/vue-styleguidist/vue-styleguidist/commit/bbc09354ee9d23a368a449260d923dc7c034650c)]: | ||
- vue-inbrowser-compiler-utils@4.47.0 | ||
## 4.44.24 | ||
@@ -4,0 +26,0 @@ |
@@ -6,6 +6,6 @@ 'use strict'; | ||
var vueInbrowserCompilerUtils = require('vue-inbrowser-compiler-utils'); | ||
var buble = require('buble'); | ||
var walkes = require('walkes'); | ||
var acorn = require('acorn'); | ||
var jsx = require('acorn-jsx'); | ||
var buble = require('buble'); | ||
var detectBrowser = require('detect-browser'); | ||
@@ -18,88 +18,79 @@ | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
const extendedParser = acorn.Parser.extend(jsx__default["default"]()); | ||
function getAst(code) { | ||
return extendedParser.parse(code, { | ||
ecmaVersion: 2019, | ||
sourceType: 'module' | ||
}); | ||
} | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
function getImports(code) { | ||
const imports = []; | ||
try { | ||
const ast = getAst(code); | ||
walkes__default["default"](ast, { | ||
ImportDeclaration(node) { | ||
imports.push(node.source.value); | ||
}, | ||
CallExpression(node) { | ||
if (node.callee.name === 'require' && node.arguments[0].value) { | ||
imports.push(node.arguments[0].value); | ||
} | ||
} | ||
}); | ||
return vueInbrowserCompilerUtils.isVue3 ? ['vue', ...imports] : imports; | ||
} | ||
catch (e) { | ||
return vueInbrowserCompilerUtils.isVue3 ? ['vue'] : []; | ||
} | ||
} | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var UNNAMED = /import\s*['"]([^'"]+)['"];?/gi; | ||
var NAMED = /import\s*(\*\s*as)?\s*(\w*?)\s*,?\s*(?:\{([\s\S]*?)\})?\s*from\s*['"]([^'"]+)['"];?/gi; | ||
const UNNAMED = /import\s*['"]([^'"]+)['"];?/gi; | ||
const NAMED = /import\s*(\*\s*as)?\s*(\w*?)\s*,?\s*(?:\{([\s\S]*?)\})?\s*from\s*['"]([^'"]+)['"];?/gi; | ||
function alias(previousKey) { | ||
var key = previousKey.trim(); | ||
var name = key.split(' as '); | ||
let key = previousKey.trim(); | ||
const name = key.split(' as '); | ||
if (name.length > 1) { | ||
key = name.shift() || ''; | ||
} | ||
return { key: key, name: name[0] }; | ||
return { key, name: name[0] }; | ||
} | ||
function generate(keys, dep, base, fn, offset) { | ||
if (offset === void 0) { offset = 0; } | ||
var depEnd = dep.split('/').pop(); | ||
var tmp = depEnd | ||
function generate(keys, dep, base, fn, offset = 0) { | ||
const depEnd = dep.split('/').pop(); | ||
const tmp = depEnd | ||
? depEnd.replace(/\W/g, '_') + '$' + offset // uniqueness | ||
: ''; | ||
var name = alias(tmp).name; | ||
dep = "".concat(fn, "('").concat(dep, "')"); | ||
var obj; | ||
var out = "const ".concat(name, " = ").concat(dep, ";"); | ||
const name = alias(tmp).name; | ||
dep = `${fn}('${dep}')`; | ||
let obj; | ||
let out = `const ${name} = ${dep};`; | ||
if (base) { | ||
out += "const ".concat(base, " = ").concat(tmp, ".default || ").concat(tmp, ";"); | ||
out += `const ${base} = ${tmp}.default || ${tmp};`; | ||
} | ||
keys.forEach(function (key) { | ||
keys.forEach(key => { | ||
obj = alias(key); | ||
out += "const ".concat(obj.name, " = ").concat(tmp, ".").concat(obj.key, ";"); | ||
out += `const ${obj.name} = ${tmp}.${obj.key};`; | ||
}); | ||
return out; | ||
} | ||
function rewriteImports (str, offset, fn) { | ||
if (fn === void 0) { fn = 'require'; } | ||
function rewriteImports (str, offset, fn = 'require') { | ||
return str | ||
.replace(NAMED, function (_, asterisk, base, req, dep) { | ||
return generate(req ? req.split(',').filter(function (d) { return d.trim(); }) : [], dep, base, fn, offset); | ||
}) | ||
.replace(UNNAMED, function (_, dep) { return "".concat(fn, "('").concat(dep, "');"); }); | ||
.replace(NAMED, (_, asterisk, base, req, dep) => generate(req ? req.split(',').filter((d) => d.trim()) : [], dep, base, fn, offset)) | ||
.replace(UNNAMED, (_, dep) => `${fn}('${dep}');`); | ||
} | ||
function transformOneImport(node, code, offset) { | ||
var start = node.start + offset; | ||
var end = node.end + offset; | ||
var statement = code.substring(start, end); | ||
var transpiledStatement = rewriteImports(statement, offset); | ||
const start = node.start + offset; | ||
const end = node.end + offset; | ||
const statement = code.substring(start, end); | ||
const transpiledStatement = rewriteImports(statement, offset); | ||
code = code.substring(0, start) + transpiledStatement + code.substring(end); | ||
offset += transpiledStatement.length - statement.length; | ||
return { code: code, offset: offset }; | ||
return { code, offset }; | ||
} | ||
var extendedParser = acorn.Parser.extend(jsx__default["default"]()); | ||
function getAst(code) { | ||
return extendedParser.parse(code, { | ||
ecmaVersion: 2019, | ||
sourceType: 'module' | ||
}); | ||
} | ||
var buildStyles = function (styles) { | ||
var _styles = ''; | ||
const buildStyles = function (styles) { | ||
let _styles = ''; | ||
if (styles) { | ||
styles.forEach(function (it) { | ||
styles.forEach(it => { | ||
if (it) { | ||
@@ -116,3 +107,3 @@ _styles += it; | ||
function getSingleFileComponentParts(code) { | ||
var parts = vueInbrowserCompilerUtils.parseComponent(code); | ||
const parts = vueInbrowserCompilerUtils.parseComponent(code); | ||
if (parts.script) { | ||
@@ -123,27 +114,11 @@ parts.script = parts.script.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, '$1'); | ||
} | ||
function injectTemplateAndParseExport(parts) { | ||
var templateString = parts.template | ||
? parts.template.replace(/`/g, '\\`').replace(/\$\{/g, '\\${') | ||
: undefined; | ||
if (!parts.script) { | ||
return { component: "{template: `".concat(templateString, "` }") }; | ||
} | ||
var comp = parseScriptCode(parts.script); | ||
if (templateString) { | ||
comp.component = "{template: `".concat(templateString, "`, ").concat(comp.component, "}"); | ||
} | ||
else { | ||
comp.component = "{".concat(comp.component, "}"); | ||
} | ||
return comp; | ||
} | ||
function parseScriptCode(code) { | ||
var preprocessing = ''; | ||
var startIndex = -1; | ||
var endIndex = -1; | ||
var offset = 0; | ||
var renderFunctionStart = -1; | ||
let preprocessing = ''; | ||
let startIndex = -1; | ||
let endIndex = -1; | ||
let offset = 0; | ||
let renderFunctionStart = -1; | ||
walkes__default["default"](getAst(code), { | ||
//export const MyComponent = {} | ||
ExportNamedDeclaration: function (node) { | ||
ExportNamedDeclaration(node, recurse, stop) { | ||
preprocessing = code.slice(0, node.start + offset); | ||
@@ -155,5 +130,6 @@ startIndex = node.declaration.declarations[0].init.start + offset; | ||
} | ||
recurse(); | ||
}, | ||
//export default {} | ||
ExportDefaultDeclaration: function (node) { | ||
ExportDefaultDeclaration(node, recurse, stop) { | ||
preprocessing = code.slice(0, node.start + offset); | ||
@@ -163,5 +139,6 @@ startIndex = node.declaration.start + offset; | ||
renderFunctionStart = getRenderFunctionStart(node.declaration); | ||
recurse(); | ||
}, | ||
//module.exports = {} | ||
AssignmentExpression: function (node) { | ||
AssignmentExpression(node, recurse, stop) { | ||
if (/exports/.test(node.left.name) || | ||
@@ -175,6 +152,7 @@ (node.left.object && | ||
} | ||
recurse(); | ||
}, | ||
// and transform import statements into require | ||
ImportDeclaration: function (node) { | ||
var ret = transformOneImport(node, code, offset); | ||
ImportDeclaration(node) { | ||
const ret = transformOneImport(node, code, offset); | ||
offset = ret.offset; | ||
@@ -192,14 +170,14 @@ code = ret.code; | ||
} | ||
var component = code.slice(startIndex + 1, endIndex - 1); | ||
const component = code.slice(startIndex + 1, endIndex - 1); | ||
return { | ||
preprocessing: preprocessing, | ||
component: component, | ||
preprocessing, | ||
component, | ||
postprocessing: code.slice(endIndex) | ||
}; | ||
} | ||
var JSX_ADDON_LENGTH = 31; | ||
const JSX_ADDON_LENGTH = 31; | ||
function getRenderFunctionStart(objectExpression) { | ||
if (objectExpression && objectExpression.properties) { | ||
var nodeProperties = objectExpression.properties; | ||
var renderFunctionObj = nodeProperties.find(function (p) { return p.key && p.key.type === 'Identifier' && p.key.name === 'render'; }); | ||
const nodeProperties = objectExpression.properties; | ||
const renderFunctionObj = nodeProperties.find((p) => p.key && p.key.type === 'Identifier' && p.key.name === 'render'); | ||
if (renderFunctionObj && renderFunctionObj.value.body) { | ||
@@ -212,3 +190,3 @@ return renderFunctionObj.value.body.start; | ||
function insertCreateElementFunction(before, after) { | ||
return "".concat(before, ";const h = this.$createElement;").concat(after); | ||
return `${before};const h = this.$createElement;${after}`; | ||
} | ||
@@ -221,10 +199,7 @@ /** | ||
function normalizeSfcComponent(code) { | ||
var parts = getSingleFileComponentParts(code); | ||
var extractedComponent = injectTemplateAndParseExport(parts); | ||
const parts = getSingleFileComponentParts(code); | ||
const { preprocessing = '', component = '', postprocessing = '' } = parts.script ? parseScriptCode(parts.script) : {}; | ||
return { | ||
script: [ | ||
extractedComponent.preprocessing, | ||
"return ".concat(extractedComponent.component), | ||
extractedComponent.postprocessing | ||
].join(';'), | ||
template: parts.template, | ||
script: [preprocessing, `return {${component}}`, postprocessing].join('\n'), | ||
style: buildStyles(parts.styles) | ||
@@ -234,4 +209,4 @@ }; | ||
var browser = detectBrowser.detect(); | ||
var BROWSERS = { | ||
const browser = detectBrowser.detect(); | ||
const BROWSERS = { | ||
chrome: 71, | ||
@@ -247,9 +222,8 @@ firefox: 64, | ||
function getTargetFromBrowser() { | ||
var _a; | ||
if ((browser === null || browser === void 0 ? void 0 : browser.version) && (browser === null || browser === void 0 ? void 0 : browser.name)) { | ||
if (isBubleBrowser(browser.name)) { | ||
var version = parseInt(browser.version, 10); | ||
return _a = {}, | ||
_a[browser.name] = version <= BROWSERS[browser.name] ? version : BROWSERS[browser.name], | ||
_a; | ||
const version = parseInt(browser.version, 10); | ||
return { | ||
[browser.name]: version <= BROWSERS[browser.name] ? version : BROWSERS[browser.name] | ||
}; | ||
} | ||
@@ -261,4 +235,7 @@ } | ||
/** | ||
* Reads the code in string and separates the javascript part and the html part | ||
* then sets the nameVarComponent variable with the value of the component parameters | ||
* Reads the code as a string, separates the javascript part from the template & style parts, | ||
* then replaces the imports with requires and returns the script code as the body of a function. | ||
* | ||
* - For Vue2 the function compiles the template into a render function and adds the new function to the evaluated code. | ||
* - For Vue3 you have to use the compileVue3Template function yourself to compile the template into a function. | ||
* @param code | ||
@@ -268,12 +245,13 @@ * @param config buble config to be used when transforming | ||
*/ | ||
function compileVueCodeForEvalFunction(code, config) { | ||
if (config === void 0) { config = {}; } | ||
var nonCompiledComponent = prepareVueCodeForEvalFunction(code, config); | ||
var target = typeof window !== 'undefined' ? getTargetFromBrowser() : {}; | ||
return __assign(__assign({}, nonCompiledComponent), { script: buble.transform(nonCompiledComponent.script, __assign({ target: target }, config)).code }); | ||
function compileVueCodeForEvalFunction(code, config = {}) { | ||
const nonCompiledComponent = prepareVueCodeForEvalFunction(code, config); | ||
const target = typeof window !== 'undefined' ? getTargetFromBrowser() : {}; | ||
const compiledComponent = Object.assign(Object.assign({}, nonCompiledComponent), { script: buble.transform(nonCompiledComponent.script, Object.assign({ target }, config)).code }); | ||
vueInbrowserCompilerUtils.compileTemplateForEval(compiledComponent); | ||
return Object.assign(Object.assign({}, compiledComponent), { raw: nonCompiledComponent }); | ||
} | ||
function prepareVueCodeForEvalFunction(code, config) { | ||
var style; | ||
var vsgMode = false; | ||
var template; | ||
let style; | ||
let vsgMode = false; | ||
let template; | ||
// if the component is written as a Vue sfc, | ||
@@ -291,9 +269,9 @@ // transform it in to a "return" | ||
if (config.jsx) { | ||
var _a = parseScriptCode(code), preprocessing = _a.preprocessing, component = _a.component, postprocessing = _a.postprocessing; | ||
const { preprocessing, component, postprocessing } = parseScriptCode(code); | ||
return { | ||
script: "".concat(preprocessing, ";return {").concat(component, "};").concat(postprocessing) | ||
script: `${preprocessing};return {${component}};${postprocessing}` | ||
}; | ||
} | ||
var findStartTemplateMatch = /^\W*</.test(code) ? { index: 0 } : code.match(/\n[\t ]*</); | ||
var limitScript = findStartTemplateMatch && findStartTemplateMatch.index !== undefined | ||
const findStartTemplateMatch = /^\W*</.test(code) ? { index: 0 } : code.match(/\n[\t ]*</); | ||
const limitScript = findStartTemplateMatch && findStartTemplateMatch.index !== undefined | ||
? findStartTemplateMatch.index | ||
@@ -305,15 +283,15 @@ : -1; | ||
} | ||
var ast = getAst(code); | ||
var offset = 0; | ||
var varNames = []; | ||
walkes__default["default"](ast, __assign({ | ||
const ast = getAst(code); | ||
let offset = 0; | ||
const varNames = []; | ||
walkes__default["default"](ast, Object.assign({ | ||
// replace `new Vue({data})` by `return {data}` | ||
ExpressionStatement: function (node) { | ||
ExpressionStatement(node) { | ||
if (node.expression.type === 'NewExpression' && node.expression.callee.name === 'Vue') { | ||
var before = code.slice(0, node.expression.start + offset); | ||
var optionsNode = node.expression.arguments && node.expression.arguments.length | ||
const before = code.slice(0, node.expression.start + offset); | ||
const optionsNode = node.expression.arguments && node.expression.arguments.length | ||
? node.expression.arguments[0] | ||
: undefined; | ||
var renderIndex = getRenderFunctionStart(optionsNode); | ||
var endIndex = optionsNode.end; | ||
const renderIndex = getRenderFunctionStart(optionsNode); | ||
let endIndex = optionsNode.end; | ||
if (renderIndex > 0 && !vueInbrowserCompilerUtils.isVue3) { | ||
@@ -323,18 +301,18 @@ code = insertCreateElementFunction(code.slice(0, renderIndex + 1), code.slice(renderIndex + 1)); | ||
} | ||
var after = optionsNode ? code.slice(optionsNode.start + offset, endIndex + offset) : ''; | ||
const after = optionsNode ? code.slice(optionsNode.start + offset, endIndex + offset) : ''; | ||
code = before + ';return ' + after; | ||
} | ||
}, | ||
}, | ||
// transform all imports into require function calls | ||
ImportDeclaration: function (node) { | ||
var ret = transformOneImport(node, code, offset); | ||
ImportDeclaration(node) { | ||
const ret = transformOneImport(node, code, offset); | ||
offset = ret.offset; | ||
code = ret.code; | ||
if (vsgMode && node.specifiers) { | ||
node.specifiers.forEach(function (s) { return varNames.push(s.local.name); }); | ||
node.specifiers.forEach((s) => varNames.push(s.local.name)); | ||
} | ||
} }, (vsgMode | ||
? { | ||
VariableDeclaration: function (node) { | ||
node.declarations.forEach(function (declaration) { | ||
VariableDeclaration(node) { | ||
node.declarations.forEach((declaration) => { | ||
if (declaration.id.name) { | ||
@@ -347,3 +325,3 @@ // simple variable declaration | ||
// const { all:names } = {all: 'foo'} | ||
declaration.id.properties.forEach(function (p) { | ||
declaration.id.properties.forEach((p) => { | ||
varNames.push(p.value.name); | ||
@@ -354,3 +332,3 @@ }); | ||
}, | ||
FunctionDeclaration: function (node) { | ||
FunctionDeclaration(node) { | ||
varNames.push(node.id.name); | ||
@@ -361,3 +339,3 @@ } | ||
if (vsgMode) { | ||
code += ";return {data:function(){return {".concat( | ||
code += `;return {data:function(){return {${ | ||
// add local vars in data | ||
@@ -367,8 +345,8 @@ // this is done through an object like {varName: varName} | ||
// the data object here | ||
varNames.map(function (varName) { return "".concat(varName, ":").concat(varName); }).join(','), "};}}"); | ||
varNames.map(varName => `${varName}:${varName}`).join(',')}};}}`; | ||
} | ||
return { | ||
script: code, | ||
style: style, | ||
template: template | ||
style, | ||
template | ||
}; | ||
@@ -385,2 +363,6 @@ } | ||
}); | ||
Object.defineProperty(exports, 'compileTemplateForEval', { | ||
enumerable: true, | ||
get: function () { return vueInbrowserCompilerUtils.compileTemplateForEval; } | ||
}); | ||
Object.defineProperty(exports, 'concatenate', { | ||
@@ -394,2 +376,7 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(exports, 'parseComponent', { | ||
enumerable: true, | ||
get: function () { return vueInbrowserCompilerUtils.parseComponent; } | ||
}); | ||
exports.compile = compileVueCodeForEvalFunction; | ||
exports.getImports = getImports; |
@@ -1,95 +0,86 @@ | ||
import { parseComponent, isVue3, isCodeVueSfc } from 'vue-inbrowser-compiler-utils'; | ||
export { adaptCreateElement, addScopedStyle, concatenate, isCodeVueSfc } from 'vue-inbrowser-compiler-utils'; | ||
import { transform } from 'buble'; | ||
import { isVue3, parseComponent, compileTemplateForEval, isCodeVueSfc } from 'vue-inbrowser-compiler-utils'; | ||
export { adaptCreateElement, addScopedStyle, compileTemplateForEval, concatenate, isCodeVueSfc, parseComponent } from 'vue-inbrowser-compiler-utils'; | ||
import walkes from 'walkes'; | ||
import { Parser } from 'acorn'; | ||
import jsx from 'acorn-jsx'; | ||
import { transform } from 'buble'; | ||
import { detect } from 'detect-browser'; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
const extendedParser = Parser.extend(jsx()); | ||
function getAst(code) { | ||
return extendedParser.parse(code, { | ||
ecmaVersion: 2019, | ||
sourceType: 'module' | ||
}); | ||
} | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
function getImports(code) { | ||
const imports = []; | ||
try { | ||
const ast = getAst(code); | ||
walkes(ast, { | ||
ImportDeclaration(node) { | ||
imports.push(node.source.value); | ||
}, | ||
CallExpression(node) { | ||
if (node.callee.name === 'require' && node.arguments[0].value) { | ||
imports.push(node.arguments[0].value); | ||
} | ||
} | ||
}); | ||
return isVue3 ? ['vue', ...imports] : imports; | ||
} | ||
catch (e) { | ||
return isVue3 ? ['vue'] : []; | ||
} | ||
} | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var UNNAMED = /import\s*['"]([^'"]+)['"];?/gi; | ||
var NAMED = /import\s*(\*\s*as)?\s*(\w*?)\s*,?\s*(?:\{([\s\S]*?)\})?\s*from\s*['"]([^'"]+)['"];?/gi; | ||
const UNNAMED = /import\s*['"]([^'"]+)['"];?/gi; | ||
const NAMED = /import\s*(\*\s*as)?\s*(\w*?)\s*,?\s*(?:\{([\s\S]*?)\})?\s*from\s*['"]([^'"]+)['"];?/gi; | ||
function alias(previousKey) { | ||
var key = previousKey.trim(); | ||
var name = key.split(' as '); | ||
let key = previousKey.trim(); | ||
const name = key.split(' as '); | ||
if (name.length > 1) { | ||
key = name.shift() || ''; | ||
} | ||
return { key: key, name: name[0] }; | ||
return { key, name: name[0] }; | ||
} | ||
function generate(keys, dep, base, fn, offset) { | ||
if (offset === void 0) { offset = 0; } | ||
var depEnd = dep.split('/').pop(); | ||
var tmp = depEnd | ||
function generate(keys, dep, base, fn, offset = 0) { | ||
const depEnd = dep.split('/').pop(); | ||
const tmp = depEnd | ||
? depEnd.replace(/\W/g, '_') + '$' + offset // uniqueness | ||
: ''; | ||
var name = alias(tmp).name; | ||
dep = "".concat(fn, "('").concat(dep, "')"); | ||
var obj; | ||
var out = "const ".concat(name, " = ").concat(dep, ";"); | ||
const name = alias(tmp).name; | ||
dep = `${fn}('${dep}')`; | ||
let obj; | ||
let out = `const ${name} = ${dep};`; | ||
if (base) { | ||
out += "const ".concat(base, " = ").concat(tmp, ".default || ").concat(tmp, ";"); | ||
out += `const ${base} = ${tmp}.default || ${tmp};`; | ||
} | ||
keys.forEach(function (key) { | ||
keys.forEach(key => { | ||
obj = alias(key); | ||
out += "const ".concat(obj.name, " = ").concat(tmp, ".").concat(obj.key, ";"); | ||
out += `const ${obj.name} = ${tmp}.${obj.key};`; | ||
}); | ||
return out; | ||
} | ||
function rewriteImports (str, offset, fn) { | ||
if (fn === void 0) { fn = 'require'; } | ||
function rewriteImports (str, offset, fn = 'require') { | ||
return str | ||
.replace(NAMED, function (_, asterisk, base, req, dep) { | ||
return generate(req ? req.split(',').filter(function (d) { return d.trim(); }) : [], dep, base, fn, offset); | ||
}) | ||
.replace(UNNAMED, function (_, dep) { return "".concat(fn, "('").concat(dep, "');"); }); | ||
.replace(NAMED, (_, asterisk, base, req, dep) => generate(req ? req.split(',').filter((d) => d.trim()) : [], dep, base, fn, offset)) | ||
.replace(UNNAMED, (_, dep) => `${fn}('${dep}');`); | ||
} | ||
function transformOneImport(node, code, offset) { | ||
var start = node.start + offset; | ||
var end = node.end + offset; | ||
var statement = code.substring(start, end); | ||
var transpiledStatement = rewriteImports(statement, offset); | ||
const start = node.start + offset; | ||
const end = node.end + offset; | ||
const statement = code.substring(start, end); | ||
const transpiledStatement = rewriteImports(statement, offset); | ||
code = code.substring(0, start) + transpiledStatement + code.substring(end); | ||
offset += transpiledStatement.length - statement.length; | ||
return { code: code, offset: offset }; | ||
return { code, offset }; | ||
} | ||
var extendedParser = Parser.extend(jsx()); | ||
function getAst(code) { | ||
return extendedParser.parse(code, { | ||
ecmaVersion: 2019, | ||
sourceType: 'module' | ||
}); | ||
} | ||
var buildStyles = function (styles) { | ||
var _styles = ''; | ||
const buildStyles = function (styles) { | ||
let _styles = ''; | ||
if (styles) { | ||
styles.forEach(function (it) { | ||
styles.forEach(it => { | ||
if (it) { | ||
@@ -106,3 +97,3 @@ _styles += it; | ||
function getSingleFileComponentParts(code) { | ||
var parts = parseComponent(code); | ||
const parts = parseComponent(code); | ||
if (parts.script) { | ||
@@ -113,27 +104,11 @@ parts.script = parts.script.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, '$1'); | ||
} | ||
function injectTemplateAndParseExport(parts) { | ||
var templateString = parts.template | ||
? parts.template.replace(/`/g, '\\`').replace(/\$\{/g, '\\${') | ||
: undefined; | ||
if (!parts.script) { | ||
return { component: "{template: `".concat(templateString, "` }") }; | ||
} | ||
var comp = parseScriptCode(parts.script); | ||
if (templateString) { | ||
comp.component = "{template: `".concat(templateString, "`, ").concat(comp.component, "}"); | ||
} | ||
else { | ||
comp.component = "{".concat(comp.component, "}"); | ||
} | ||
return comp; | ||
} | ||
function parseScriptCode(code) { | ||
var preprocessing = ''; | ||
var startIndex = -1; | ||
var endIndex = -1; | ||
var offset = 0; | ||
var renderFunctionStart = -1; | ||
let preprocessing = ''; | ||
let startIndex = -1; | ||
let endIndex = -1; | ||
let offset = 0; | ||
let renderFunctionStart = -1; | ||
walkes(getAst(code), { | ||
//export const MyComponent = {} | ||
ExportNamedDeclaration: function (node) { | ||
ExportNamedDeclaration(node, recurse, stop) { | ||
preprocessing = code.slice(0, node.start + offset); | ||
@@ -145,5 +120,6 @@ startIndex = node.declaration.declarations[0].init.start + offset; | ||
} | ||
recurse(); | ||
}, | ||
//export default {} | ||
ExportDefaultDeclaration: function (node) { | ||
ExportDefaultDeclaration(node, recurse, stop) { | ||
preprocessing = code.slice(0, node.start + offset); | ||
@@ -153,5 +129,6 @@ startIndex = node.declaration.start + offset; | ||
renderFunctionStart = getRenderFunctionStart(node.declaration); | ||
recurse(); | ||
}, | ||
//module.exports = {} | ||
AssignmentExpression: function (node) { | ||
AssignmentExpression(node, recurse, stop) { | ||
if (/exports/.test(node.left.name) || | ||
@@ -165,6 +142,7 @@ (node.left.object && | ||
} | ||
recurse(); | ||
}, | ||
// and transform import statements into require | ||
ImportDeclaration: function (node) { | ||
var ret = transformOneImport(node, code, offset); | ||
ImportDeclaration(node) { | ||
const ret = transformOneImport(node, code, offset); | ||
offset = ret.offset; | ||
@@ -182,14 +160,14 @@ code = ret.code; | ||
} | ||
var component = code.slice(startIndex + 1, endIndex - 1); | ||
const component = code.slice(startIndex + 1, endIndex - 1); | ||
return { | ||
preprocessing: preprocessing, | ||
component: component, | ||
preprocessing, | ||
component, | ||
postprocessing: code.slice(endIndex) | ||
}; | ||
} | ||
var JSX_ADDON_LENGTH = 31; | ||
const JSX_ADDON_LENGTH = 31; | ||
function getRenderFunctionStart(objectExpression) { | ||
if (objectExpression && objectExpression.properties) { | ||
var nodeProperties = objectExpression.properties; | ||
var renderFunctionObj = nodeProperties.find(function (p) { return p.key && p.key.type === 'Identifier' && p.key.name === 'render'; }); | ||
const nodeProperties = objectExpression.properties; | ||
const renderFunctionObj = nodeProperties.find((p) => p.key && p.key.type === 'Identifier' && p.key.name === 'render'); | ||
if (renderFunctionObj && renderFunctionObj.value.body) { | ||
@@ -202,3 +180,3 @@ return renderFunctionObj.value.body.start; | ||
function insertCreateElementFunction(before, after) { | ||
return "".concat(before, ";const h = this.$createElement;").concat(after); | ||
return `${before};const h = this.$createElement;${after}`; | ||
} | ||
@@ -211,10 +189,7 @@ /** | ||
function normalizeSfcComponent(code) { | ||
var parts = getSingleFileComponentParts(code); | ||
var extractedComponent = injectTemplateAndParseExport(parts); | ||
const parts = getSingleFileComponentParts(code); | ||
const { preprocessing = '', component = '', postprocessing = '' } = parts.script ? parseScriptCode(parts.script) : {}; | ||
return { | ||
script: [ | ||
extractedComponent.preprocessing, | ||
"return ".concat(extractedComponent.component), | ||
extractedComponent.postprocessing | ||
].join(';'), | ||
template: parts.template, | ||
script: [preprocessing, `return {${component}}`, postprocessing].join('\n'), | ||
style: buildStyles(parts.styles) | ||
@@ -224,4 +199,4 @@ }; | ||
var browser = detect(); | ||
var BROWSERS = { | ||
const browser = detect(); | ||
const BROWSERS = { | ||
chrome: 71, | ||
@@ -237,9 +212,8 @@ firefox: 64, | ||
function getTargetFromBrowser() { | ||
var _a; | ||
if ((browser === null || browser === void 0 ? void 0 : browser.version) && (browser === null || browser === void 0 ? void 0 : browser.name)) { | ||
if (isBubleBrowser(browser.name)) { | ||
var version = parseInt(browser.version, 10); | ||
return _a = {}, | ||
_a[browser.name] = version <= BROWSERS[browser.name] ? version : BROWSERS[browser.name], | ||
_a; | ||
const version = parseInt(browser.version, 10); | ||
return { | ||
[browser.name]: version <= BROWSERS[browser.name] ? version : BROWSERS[browser.name] | ||
}; | ||
} | ||
@@ -251,4 +225,7 @@ } | ||
/** | ||
* Reads the code in string and separates the javascript part and the html part | ||
* then sets the nameVarComponent variable with the value of the component parameters | ||
* Reads the code as a string, separates the javascript part from the template & style parts, | ||
* then replaces the imports with requires and returns the script code as the body of a function. | ||
* | ||
* - For Vue2 the function compiles the template into a render function and adds the new function to the evaluated code. | ||
* - For Vue3 you have to use the compileVue3Template function yourself to compile the template into a function. | ||
* @param code | ||
@@ -258,12 +235,13 @@ * @param config buble config to be used when transforming | ||
*/ | ||
function compileVueCodeForEvalFunction(code, config) { | ||
if (config === void 0) { config = {}; } | ||
var nonCompiledComponent = prepareVueCodeForEvalFunction(code, config); | ||
var target = typeof window !== 'undefined' ? getTargetFromBrowser() : {}; | ||
return __assign(__assign({}, nonCompiledComponent), { script: transform(nonCompiledComponent.script, __assign({ target: target }, config)).code }); | ||
function compileVueCodeForEvalFunction(code, config = {}) { | ||
const nonCompiledComponent = prepareVueCodeForEvalFunction(code, config); | ||
const target = typeof window !== 'undefined' ? getTargetFromBrowser() : {}; | ||
const compiledComponent = Object.assign(Object.assign({}, nonCompiledComponent), { script: transform(nonCompiledComponent.script, Object.assign({ target }, config)).code }); | ||
compileTemplateForEval(compiledComponent); | ||
return Object.assign(Object.assign({}, compiledComponent), { raw: nonCompiledComponent }); | ||
} | ||
function prepareVueCodeForEvalFunction(code, config) { | ||
var style; | ||
var vsgMode = false; | ||
var template; | ||
let style; | ||
let vsgMode = false; | ||
let template; | ||
// if the component is written as a Vue sfc, | ||
@@ -281,9 +259,9 @@ // transform it in to a "return" | ||
if (config.jsx) { | ||
var _a = parseScriptCode(code), preprocessing = _a.preprocessing, component = _a.component, postprocessing = _a.postprocessing; | ||
const { preprocessing, component, postprocessing } = parseScriptCode(code); | ||
return { | ||
script: "".concat(preprocessing, ";return {").concat(component, "};").concat(postprocessing) | ||
script: `${preprocessing};return {${component}};${postprocessing}` | ||
}; | ||
} | ||
var findStartTemplateMatch = /^\W*</.test(code) ? { index: 0 } : code.match(/\n[\t ]*</); | ||
var limitScript = findStartTemplateMatch && findStartTemplateMatch.index !== undefined | ||
const findStartTemplateMatch = /^\W*</.test(code) ? { index: 0 } : code.match(/\n[\t ]*</); | ||
const limitScript = findStartTemplateMatch && findStartTemplateMatch.index !== undefined | ||
? findStartTemplateMatch.index | ||
@@ -295,15 +273,15 @@ : -1; | ||
} | ||
var ast = getAst(code); | ||
var offset = 0; | ||
var varNames = []; | ||
walkes(ast, __assign({ | ||
const ast = getAst(code); | ||
let offset = 0; | ||
const varNames = []; | ||
walkes(ast, Object.assign({ | ||
// replace `new Vue({data})` by `return {data}` | ||
ExpressionStatement: function (node) { | ||
ExpressionStatement(node) { | ||
if (node.expression.type === 'NewExpression' && node.expression.callee.name === 'Vue') { | ||
var before = code.slice(0, node.expression.start + offset); | ||
var optionsNode = node.expression.arguments && node.expression.arguments.length | ||
const before = code.slice(0, node.expression.start + offset); | ||
const optionsNode = node.expression.arguments && node.expression.arguments.length | ||
? node.expression.arguments[0] | ||
: undefined; | ||
var renderIndex = getRenderFunctionStart(optionsNode); | ||
var endIndex = optionsNode.end; | ||
const renderIndex = getRenderFunctionStart(optionsNode); | ||
let endIndex = optionsNode.end; | ||
if (renderIndex > 0 && !isVue3) { | ||
@@ -313,18 +291,18 @@ code = insertCreateElementFunction(code.slice(0, renderIndex + 1), code.slice(renderIndex + 1)); | ||
} | ||
var after = optionsNode ? code.slice(optionsNode.start + offset, endIndex + offset) : ''; | ||
const after = optionsNode ? code.slice(optionsNode.start + offset, endIndex + offset) : ''; | ||
code = before + ';return ' + after; | ||
} | ||
}, | ||
}, | ||
// transform all imports into require function calls | ||
ImportDeclaration: function (node) { | ||
var ret = transformOneImport(node, code, offset); | ||
ImportDeclaration(node) { | ||
const ret = transformOneImport(node, code, offset); | ||
offset = ret.offset; | ||
code = ret.code; | ||
if (vsgMode && node.specifiers) { | ||
node.specifiers.forEach(function (s) { return varNames.push(s.local.name); }); | ||
node.specifiers.forEach((s) => varNames.push(s.local.name)); | ||
} | ||
} }, (vsgMode | ||
? { | ||
VariableDeclaration: function (node) { | ||
node.declarations.forEach(function (declaration) { | ||
VariableDeclaration(node) { | ||
node.declarations.forEach((declaration) => { | ||
if (declaration.id.name) { | ||
@@ -337,3 +315,3 @@ // simple variable declaration | ||
// const { all:names } = {all: 'foo'} | ||
declaration.id.properties.forEach(function (p) { | ||
declaration.id.properties.forEach((p) => { | ||
varNames.push(p.value.name); | ||
@@ -344,3 +322,3 @@ }); | ||
}, | ||
FunctionDeclaration: function (node) { | ||
FunctionDeclaration(node) { | ||
varNames.push(node.id.name); | ||
@@ -351,3 +329,3 @@ } | ||
if (vsgMode) { | ||
code += ";return {data:function(){return {".concat( | ||
code += `;return {data:function(){return {${ | ||
// add local vars in data | ||
@@ -357,11 +335,11 @@ // this is done through an object like {varName: varName} | ||
// the data object here | ||
varNames.map(function (varName) { return "".concat(varName, ":").concat(varName); }).join(','), "};}}"); | ||
varNames.map(varName => `${varName}:${varName}`).join(',')}};}}`; | ||
} | ||
return { | ||
script: code, | ||
style: style, | ||
template: template | ||
style, | ||
template | ||
}; | ||
} | ||
export { compileVueCodeForEvalFunction as compile }; | ||
export { compileVueCodeForEvalFunction as compile, getImports }; |
{ | ||
"name": "vue-inbrowser-compiler", | ||
"version": "4.44.24", | ||
"version": "4.50.0", | ||
"description": "compile vue single file components right in your browser", | ||
"module": "lib/vue-inbrowser-compiler.esm.js", | ||
"main": "lib/vue-inbrowser-compiler.cjs.js", | ||
"types": "lib/types/index.d.ts", | ||
"types": "lib/index.d.ts", | ||
"keywords": [ | ||
@@ -22,3 +22,3 @@ "vue", | ||
"detect-browser": "^5.2.0", | ||
"vue-inbrowser-compiler-utils": "^4.44.23", | ||
"vue-inbrowser-compiler-utils": "^4.50.0", | ||
"walkes": "^0.2.1" | ||
@@ -29,8 +29,10 @@ }, | ||
"@rollup/plugin-node-resolve": "9.0.0", | ||
"@rollup/plugin-typescript": "8.3.0", | ||
"@rollup/plugin-typescript": "8.3.4", | ||
"@types/buble": "0.20.1", | ||
"@vue/test-utils": "1.3.0", | ||
"rollup": "2.66.1", | ||
"typescript": "4.5.5", | ||
"vue": "2.6.14" | ||
"rollup": "2.77.2", | ||
"tslib": "2.4.0", | ||
"typescript": "4.7.4", | ||
"vue": "2.7.8", | ||
"vue-template-compiler": "2.7.8" | ||
}, | ||
@@ -51,4 +53,3 @@ "peerDependencies": { | ||
"compile:watch": "rollup -c --watch" | ||
}, | ||
"readme": "# vue-inbrowser-compiler\n\nCompile vue components code into vue components objects inside of your browser\n\n## install\n\n```bash\nyarn add vue-inbrowser-compiler\n```\n\n## usage\n\nThis library is meant to help write components for vue that can be edited through text.\n\n### compile\n\nCompiles a string of pseudo javascript code written in es2015. It returns the body of a function as a string. Once you execute the function, it will return a VueJS component.\n\n**prototype**: `compile(code: string, config: BubleConfig): {script: string, style: string}`\n\n```js\nimport { compile } from 'vue-inbrowser-compiler'\n\n/**\n * render a component\n */\nfunction getComponent(code) {\n const conpiledCode = compile(\n code,\n // pass in config options to buble to set up the output\n {\n target: { ie: 11 }\n }\n )\n const func = new Function(conpiledCode.script)\n return func()\n}\n```\n\nThe formats of the code here are the same as vue-live and vue-styleguidist\n\n#### pseudo jsx\n\nMost common use case is a simple vue template.\n\n```html\n<button color=\"blue\">Test This Buttton</button>\n```\n\nwill be transformed into\n\n```js\nreturn {\n template: '<Button color=\"blue\">Test This Buttton</Button>'\n}\n```\n\nA more advanced use case if you want to use variables\n\n```jsx\n// initialize variables here and use them below\nlet show = true\nlet today = new Date();\n\n// starting from the first line that starts with a <tag>,\n// the rest is considered a template\n<input type=\"checkbox\" v-model=\"show\">\n<date-picker\n style=\"text-align:center;\"\n v-if=\"show\"\n :value=\"today\"/>\n```\n\nwill turn into\n\n```js\nlet show = true\nlet today = new Date();\n\nreturn {\n data(){\n return{\n show: show,\n today: today\n }\n }\n template: `<input type=\"checkbox\" v-model=\"show\">\n<date-picker\n style=\"text-align:center;\"\n v-if=\"show\"\n :value=\"today\"/>`\n}\n```\n\n#### Vue apps\n\nA simple way to make it explicit\n\n```js\nnew Vue({\n template: `\n<div>\n <input v-model=\"value\" type=\"checkbox\">\n <h1 v-if=\"value\">I am checked</h1>\n</div>`,\n data() {\n return {\n value: false\n }\n }\n})\n```\n\n#### Single File Components\n\n```html\n<template>\n <div class=\"hello\">\n <h1>Colored Text</h1>\n <button>{{ msg }}</button>\n </div>\n</template>\n\n<script>\n export default {\n data() {\n return {\n msg: 'Push Me'\n }\n }\n }\n</script>\n\n<style>\n .hello {\n text-align: center;\n color: #900;\n }\n</style>\n```\n\n### isCodeVueSfc\n\nDetects if the code given corresponds to a VueJS [Single File Component](https://vuejs.org/v2/guide/single-file-components.html). If there is a `<template>` or a `<script>` tag, it will return true, otherwise return false.\n\n**prototype**: `isCodeVueSfc(code: string):boolean`\n\n```js\nimport { isCodeVueSfc } from 'vue-inbrowser-compiler'\n\nif (isCodeVueSfc(code)) {\n doStuffForSFC(code)\n} else {\n doStuffForJSFiles(code)\n}\n```\n\n### addScopedStyle\n\nTakes the css style passed in first argument, scopes it using the suffix and adds it to the current page.\n\n**prototype**: `addScopedStyle(css: string, suffix: string):void`\n\n### adaptCreateElement\n\nIn order to make JSX work with the compiler, you need to specify a pragma. Since tis pragma has a different form for VueJs than for ReactJs, we need to provide an adapter.\n\n```js\nimport { compile, adaptCreateElement } from 'vue-inbrowser-compiler'\n\n/**\n * render a JSX component\n */\nfunction getComponent(code) {\n const conpiledCode = compile(\n code,\n // in this config we set up the jsx pragma to a higher order function\n {\n jsx: '__pragma__(h)'\n }\n )\n const func = new Function('__pragma__', conpiledCode.script)\n // now pass the higher order function to the function call\n return func(adaptCreateElement)\n}\n```\n" | ||
} | ||
} |
@@ -28,3 +28,4 @@ import * as path from 'path' | ||
declarationDir: 'types', | ||
rootDir: 'src' | ||
rootDir: 'src', | ||
include: ['**/*.ts', '../../../@types/**/*.ts'] | ||
}), | ||
@@ -31,0 +32,0 @@ // Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs, `require()`) |
/* eslint-disable no-new-func */ | ||
import compileVueCodeForEvalFunction from './compileVueCodeForEvalFunction' | ||
import compileVueCodeForEvalFunction, { | ||
getEvaluableVue3RenderFunctionBody | ||
} from './compileVueCodeForEvalFunction' | ||
@@ -156,7 +158,8 @@ describe('compileVueCodeForEvalFunction', () => { | ||
const comp = (function() { | ||
;return {template: \` | ||
<div/> | ||
\`, | ||
return { | ||
data(){ | ||
@@ -167,4 +170,8 @@ return { | ||
} | ||
}; | ||
" | ||
} | ||
})() | ||
comp.render = function() {with(this){return _c('div')}} | ||
return comp" | ||
`) | ||
@@ -171,0 +178,0 @@ }) |
import { transform, TransformOptions } from 'buble' | ||
import walkes from 'walkes' | ||
import { isCodeVueSfc, isVue3 } from 'vue-inbrowser-compiler-utils' | ||
import { | ||
EvaluableComponent, | ||
isCodeVueSfc, | ||
isVue3, | ||
compileTemplateForEval | ||
} from 'vue-inbrowser-compiler-utils' | ||
import transformOneImport from './transformOneImport' | ||
@@ -14,11 +19,15 @@ import normalizeSfcComponent, { | ||
interface EvaluableComponent { | ||
script: string | ||
template?: string | ||
style?: string | ||
interface EvaluableComponentWithSource extends EvaluableComponent { | ||
raw: { | ||
script: string | ||
template?: string | ||
} | ||
} | ||
/** | ||
* Reads the code in string and separates the javascript part and the html part | ||
* then sets the nameVarComponent variable with the value of the component parameters | ||
* Reads the code as a string, separates the javascript part from the template & style parts, | ||
* then replaces the imports with requires and returns the script code as the body of a function. | ||
* | ||
* - For Vue2 the function compiles the template into a render function and adds the new function to the evaluated code. | ||
* - For Vue3 you have to use the compileVue3Template function yourself to compile the template into a function. | ||
* @param code | ||
@@ -31,9 +40,17 @@ * @param config buble config to be used when transforming | ||
config: TransformOptions = {} | ||
): EvaluableComponent { | ||
): EvaluableComponentWithSource { | ||
const nonCompiledComponent = prepareVueCodeForEvalFunction(code, config) | ||
const target = typeof window !== 'undefined' ? getTargetFromBrowser() : {} | ||
return { | ||
const compiledComponent = { | ||
...nonCompiledComponent, | ||
script: transform(nonCompiledComponent.script, { target, ...config }).code | ||
} | ||
compileTemplateForEval(compiledComponent) | ||
return { | ||
...compiledComponent, | ||
raw: nonCompiledComponent | ||
} | ||
} | ||
@@ -40,0 +57,0 @@ |
@@ -5,4 +5,7 @@ export { | ||
concatenate, | ||
isCodeVueSfc | ||
isCodeVueSfc, | ||
compileTemplateForEval, | ||
parseComponent | ||
} from 'vue-inbrowser-compiler-utils' | ||
export { default as getImports } from './getImports' | ||
export { default as compile } from './compileVueCodeForEvalFunction' |
@@ -23,3 +23,3 @@ import normalizeSfcComponent from './normalizeSfcComponent' | ||
</script>`) | ||
expect(evalFunction(sut)).toMatchObject({ template: '\n\n<div/>\n', param: 'Foo' }) | ||
expect(evalFunction(sut)).toMatchObject({ param: 'Foo' }) | ||
}) | ||
@@ -39,3 +39,3 @@ | ||
</script>`) | ||
expect(evalFunction(sut)).toMatchObject({ template: '\n\n<div/>\n', param: 'Foo' }) | ||
expect(evalFunction(sut)).toMatchObject({ param: 'Foo' }) | ||
}) | ||
@@ -54,3 +54,3 @@ | ||
</script>`) | ||
expect(evalFunction(sut)).toMatchObject({ template: '\n\n<div/>\n', param: 'Foo' }) | ||
expect(evalFunction(sut)).toMatchObject({ param: 'Foo' }) | ||
}) | ||
@@ -57,0 +57,0 @@ |
import walkes from 'walkes' | ||
import { parseComponent, VsgSFCDescriptor, isVue3 } from 'vue-inbrowser-compiler-utils' | ||
import { parseComponent, isVue3 } from 'vue-inbrowser-compiler-utils' | ||
import getAst from './getAst' | ||
@@ -29,24 +29,2 @@ import transformOneImport from './transformOneImport' | ||
function injectTemplateAndParseExport(parts: VsgSFCDescriptor): { | ||
preprocessing?: string | ||
component: string | ||
postprocessing?: string | ||
} { | ||
const templateString = parts.template | ||
? parts.template.replace(/`/g, '\\`').replace(/\$\{/g, '\\${') | ||
: undefined | ||
if (!parts.script) { | ||
return { component: `{template: \`${templateString}\` }` } | ||
} | ||
const comp = parseScriptCode(parts.script) | ||
if (templateString) { | ||
comp.component = `{template: \`${templateString}\`, ${comp.component}}` | ||
} else { | ||
comp.component = `{${comp.component}}` | ||
} | ||
return comp | ||
} | ||
export function parseScriptCode(code: string): { | ||
@@ -64,3 +42,3 @@ preprocessing?: string | ||
//export const MyComponent = {} | ||
ExportNamedDeclaration(node: any) { | ||
ExportNamedDeclaration(node: any, recurse: () => void, stop: () => void) { | ||
preprocessing = code.slice(0, node.start + offset) | ||
@@ -72,5 +50,6 @@ startIndex = node.declaration.declarations[0].init.start + offset | ||
} | ||
recurse() | ||
}, | ||
//export default {} | ||
ExportDefaultDeclaration(node: any) { | ||
ExportDefaultDeclaration(node: any, recurse: () => void, stop: () => void) { | ||
preprocessing = code.slice(0, node.start + offset) | ||
@@ -80,5 +59,6 @@ startIndex = node.declaration.start + offset | ||
renderFunctionStart = getRenderFunctionStart(node.declaration) | ||
recurse() | ||
}, | ||
//module.exports = {} | ||
AssignmentExpression(node: any) { | ||
AssignmentExpression(node: any, recurse: () => void, stop: () => void) { | ||
if ( | ||
@@ -94,3 +74,5 @@ /exports/.test(node.left.name) || | ||
} | ||
recurse() | ||
}, | ||
// and transform import statements into require | ||
@@ -146,13 +128,18 @@ ImportDeclaration(node: any) { | ||
*/ | ||
export default function normalizeSfcComponent(code: string): { script: string; style?: string } { | ||
export default function normalizeSfcComponent(code: string): { | ||
script: string | ||
style?: string | ||
template?: string | ||
} { | ||
const parts = getSingleFileComponentParts(code) | ||
const extractedComponent = injectTemplateAndParseExport(parts) | ||
const { | ||
preprocessing = '', | ||
component = '', | ||
postprocessing = '' | ||
} = parts.script ? parseScriptCode(parts.script) : {} | ||
return { | ||
script: [ | ||
extractedComponent.preprocessing, | ||
`return ${extractedComponent.component}`, | ||
extractedComponent.postprocessing | ||
].join(';'), | ||
template: parts.template, | ||
script: [preprocessing, `return {${component}}`, postprocessing].join('\n'), | ||
style: buildStyles(parts.styles) | ||
} | ||
} |
@@ -9,4 +9,4 @@ { | ||
}, | ||
"include": ["src/**/*.ts"], | ||
"include": ["src/**/*.ts", "../../@types/**/*.ts"], | ||
"exclude": ["src/**/*.spec.ts"] | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
30
1871
80755
10