vite-plugin-vue2
Version:
Vite plugin for Vue2
276 lines • 12.4 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.cleanUrl = exports.hashRE = exports.queryRE = exports.FS_PREFIX = exports.transformMain = void 0;
const querystring_1 = __importDefault(require("querystring"));
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const source_map_1 = require("source-map");
const Vite = __importStar(require("vite"));
const descriptorCache_1 = require("./utils/descriptorCache");
const rewriteDefault_1 = require("./utils/rewriteDefault");
const index_1 = require("./index");
async function transformMain(code, filePath, options, pluginContext) {
const descriptor = (0, descriptorCache_1.createDescriptor)(code, filePath, options);
const hasFunctional = descriptor.template && descriptor.template.attrs.functional;
// template
const { code: templateCode, templateRequest } = await genTemplateRequest(filePath, descriptor, pluginContext);
// script
const scriptVar = '__vue2_script';
const { scriptCode, map: scriptMap } = await genScriptCode(scriptVar, descriptor, filePath, options, pluginContext);
// style
const cssModuleVar = '__cssModules';
const { scoped, stylesCode } = await genStyleRequest(cssModuleVar, descriptor, filePath, pluginContext);
let result = `${`${scriptCode}
${templateCode}
const ${cssModuleVar} = {}
${stylesCode}
/* normalize component */
import __vue2_normalizer from "${index_1.vueComponentNormalizer}"
var __component__ = /*#__PURE__*/__vue2_normalizer(
__vue2_script,
__vue2_render,
__vue2_staticRenderFns,
${hasFunctional ? 'true' : 'false'},
__vue2_injectStyles,
${scoped ? JSON.stringify(descriptor.id) : 'null'},
null,
null
)
`.trim()}\n`;
result += `
function __vue2_injectStyles (context) {
for(let o in ${cssModuleVar}){
this[o] = ${cssModuleVar}[o]
}
}\n`;
// custom block
result += await genCustomBlockCode(filePath, descriptor, pluginContext);
// Expose filename. This is used by the devtools and Vue runtime warnings.
if (!options.isProduction) {
// Expose the file's full path in development, so that it can be opened
// from the devtools.
result += `\n__component__.options.__file = ${JSON.stringify(path_1.default.relative(options.root, filePath).replace(/\\/g, '/'))}`;
}
// else if (options.exposeFilename) {
// // Libraries can opt-in to expose their components' filenames in production builds.
// // For security reasons, only expose the file's basename in production.
// code += `\n__component__.options.__file = ${JSON.stringify(filePath)}`
// }
if (options.devServer && !options.isProduction) {
result += genHmrCode(options.root, descriptor.id, !!hasFunctional, templateRequest);
}
let map = scriptMap;
// if script source map is undefined, generate an emty souce map so that
// rollup wont complain at build time when using sourceMap option
if (!map) {
const emptyMapGen = new source_map_1.SourceMapGenerator({
file: filePath.replace(/\\/g, '/'),
sourceRoot: options.root.replace(/\\/g, '/'),
});
emptyMapGen.setSourceContent(filePath, code);
map = JSON.parse(emptyMapGen.toString());
}
result += '\nexport default /*#__PURE__*/(function () { return __component__.exports })()';
return {
code: result,
map,
};
}
exports.transformMain = transformMain;
const exportDefaultClassRE = /export\s+default\s+class\s+([\w$]+)/;
async function genScriptCode(scriptVar, descriptor, filename, options, _pluginContext) {
var _a, _b, _c;
const { script } = descriptor;
let scriptCode = `const ${scriptVar} = {}`;
if (!script)
return { scriptCode };
let map;
if (script) {
// If the script is js/ts and has no external src, it can be directly placed
// in the main module.
if ((!script.lang || (script.lang === 'ts' && options.devServer))
&& !script.src) {
const classMatch = script.content.match(exportDefaultClassRE);
if (classMatch) {
scriptCode = `${script.content.replace(exportDefaultClassRE, 'class $1')}\nconst ${scriptVar} = ${classMatch[1]}`;
}
else {
scriptCode = (0, rewriteDefault_1.rewriteDefault)(script.content, scriptVar);
}
map = script.map;
if (script.lang === 'ts') {
// transformWithEsbuild has been exported since vite@2.6.0-beta.0
const transformWithEsbuild = (_a = Vite.transformWithEsbuild) !== null && _a !== void 0 ? _a : options.devServer.transformWithEsbuild;
const result = await transformWithEsbuild(scriptCode, filename, { loader: 'ts', target: options.target }, map);
scriptCode = result.code;
map = result.map;
// restore esbuild missing sourcemap fields from previous compilation
if (!map.file && ((_b = script.map) === null || _b === void 0 ? void 0 : _b.file))
map.file = script.map.file;
if (!map.sourcesContent && ((_c = script.map) === null || _c === void 0 ? void 0 : _c.sourcesContent))
map.sourcesContent = script.map.sourcesContent;
}
}
else {
const src = script.src || filename;
const langFallback = (script.src && path_1.default.extname(src).slice(1)) || 'js';
const attrsQuery = attrsToQuery(script.attrs, langFallback);
const srcQuery = script.src ? '&src' : '';
const from = script.src ? `&from=${encodeURIComponent(filename)}` : '';
const query = `?vue&type=script${srcQuery}${from}${attrsQuery}`;
const request = JSON.stringify(src + query);
scriptCode
= `import ${scriptVar} from ${request}\n` + `export * from ${request}`; // support named exports
}
}
return {
scriptCode,
map: map,
};
}
async function genTemplateRequest(filename, descriptor, _pluginContext) {
const template = descriptor.template;
if (!template)
return { code: 'let __vue2_render, __vue2_staticRenderFns' };
const src = template.src || filename;
const srcQuery = template.src ? '&src' : '';
const from = template.src ? `&from=${encodeURIComponent(filename)}` : '';
const attrsQuery = attrsToQuery(template.attrs, 'js', true);
const query = `?vue${from}&type=template${srcQuery}${attrsQuery}`;
const templateRequest = src + query;
return {
code: `import { render as __vue2_render, staticRenderFns as __vue2_staticRenderFns } from ${JSON.stringify(templateRequest)}`,
templateRequest,
};
}
async function genCustomBlockCode(filename, descriptor, _pluginContext) {
let code = '';
await Promise.all(descriptor.customBlocks.map(async (block, index) => {
const blockSrc = typeof block.attrs.src === 'string' ? block.attrs.src : '';
const src = blockSrc || filename;
const attrsQuery = attrsToQuery(block.attrs, path_1.default.extname(blockSrc) || block.type);
const srcQuery = block.attrs.src ? '&src' : '';
const from = block.attrs.src
? `&from=${encodeURIComponent(filename)}`
: '';
const query = `?vue&type=${block.type}&index=${index}${srcQuery}${from}${attrsQuery}`;
const request = JSON.stringify(src + query);
code += `import block${index} from ${request}\n`;
code += `if (typeof block${index} === 'function') block${index}(__component__)\n`;
}));
return code;
}
function genHmrCode(root, id, functional, templateRequest) {
const idJSON = JSON.stringify(id);
return `\n/* hot reload */
import __VUE_HMR_RUNTIME__ from ${JSON.stringify(index_1.vueHotReload)}
import __VUE_IDENTIFIER__ from "vue"
__VUE_HMR_RUNTIME__.install(__VUE_IDENTIFIER__)
if(!import.meta.env.SSR && __VUE_HMR_RUNTIME__.compatible){
if (!__VUE_HMR_RUNTIME__.isRecorded(${idJSON})) {
__VUE_HMR_RUNTIME__.createRecord(${idJSON}, __component__.options)
}
import.meta.hot.accept((update) => {
__VUE_HMR_RUNTIME__.${functional ? 'rerender' : 'reload'}(${idJSON}, update.default)
})
${templateRequest
? `import.meta.hot.accept(${JSON.stringify(normalizeDevPath(root, templateRequest))}, (update) => {
__VUE_HMR_RUNTIME__.rerender(${idJSON}, update)
})`
: ''}
}`;
}
async function genStyleRequest(cssModuleVar, descriptor, filename, _pluginContext) {
let scoped = false;
let stylesCode = '';
for (let i = 0; i < descriptor.styles.length; i++) {
const style = descriptor.styles[i];
if (!style.src && (!style.content || !style.content.trim()))
continue;
const src = style.src || filename;
const attrsQuery = attrsToQuery(style.attrs, 'css');
const srcQuery = style.src ? '&src' : '';
const from = style.src ? `&from=${encodeURIComponent(filename)}` : '';
const query = `?vue&type=style&index=${i}${from}${srcQuery}`;
const styleRequest = src + query + attrsQuery;
if (style.scoped)
scoped = true;
if (style.module) {
stylesCode += genCSSModulesCode(i, styleRequest, style.module, cssModuleVar);
}
else {
stylesCode += `\nimport ${JSON.stringify(styleRequest)}`;
}
}
return { scoped, stylesCode };
}
function genCSSModulesCode(index, request, moduleName, cssModuleVar) {
const styleVar = `__style${index}`;
const exposedName = typeof moduleName === 'string' ? moduleName : '$style';
// inject `.module` before extension so vite handles it as css module
const moduleRequest = request.replace(/\.(\w+)$/, '.module.$1');
return (`\nimport ${styleVar} from ${JSON.stringify(moduleRequest)}`
+ `\n${cssModuleVar}["${exposedName}"] = ${styleVar}`);
}
// these are built-in query parameters so should be ignored
// if the user happen to add them as attrs
const ignoreList = ['id', 'index', 'src', 'type', 'lang', 'module'];
function attrsToQuery(attrs, langFallback, forceLangFallback = false) {
let query = '';
for (const name in attrs) {
const value = attrs[name];
if (!ignoreList.includes(name)) {
query += `&${querystring_1.default.escape(name)}${value ? `=${querystring_1.default.escape(String(value))}` : ''}`;
}
}
if (langFallback || attrs.lang) {
query
+= 'lang' in attrs
? forceLangFallback
? `&lang.${langFallback}`
: `&lang.${attrs.lang}`
: `&lang.${langFallback}`;
}
return query;
}
exports.FS_PREFIX = '/@fs/';
function normalizeDevPath(root, id) {
if (id.startsWith(`${root}/`))
return id.slice(root.length);
else if (fs_1.default.existsSync(cleanUrl(id)))
return exports.FS_PREFIX + id;
return id;
}
exports.queryRE = /\?.*$/;
exports.hashRE = /#.*$/;
function cleanUrl(url) {
return url.replace(exports.hashRE, '').replace(exports.queryRE, '');
}
exports.cleanUrl = cleanUrl;
//# sourceMappingURL=main.js.map
;