vue-pure-admin/node_modules/vite/dist/node/server/serverPluginModuleRewrite.js
2021-03-01 15:06:11 +08:00

220 lines
10 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveImport = exports.rewriteImports = exports.moduleRewritePlugin = void 0;
const path_1 = __importDefault(require("path"));
const lru_cache_1 = __importDefault(require("lru-cache"));
const magic_string_1 = __importDefault(require("magic-string"));
const es_module_lexer_1 = require("es-module-lexer");
const resolver_1 = require("../resolver");
const serverPluginHmr_1 = require("./serverPluginHmr");
const serverPluginClient_1 = require("./serverPluginClient");
const utils_1 = require("../utils");
const chalk_1 = __importDefault(require("chalk"));
const cssUtils_1 = require("../utils/cssUtils");
const serverPluginEnv_1 = require("./serverPluginEnv");
const fs_extra_1 = __importDefault(require("fs-extra"));
const debug = require('debug')('vite:rewrite');
const rewriteCache = new lru_cache_1.default({ max: 1024 });
// Plugin for rewriting served js.
// - Rewrites named module imports to `/@modules/:id` requests, e.g.
// "vue" => "/@modules/vue"
// - Rewrites files containing HMR code (reference to `import.meta.hot`) to
// inject `import.meta.hot` and track HMR boundary accept whitelists.
// - Also tracks importer/importee relationship graph during the rewrite.
// The graph is used by the HMR plugin to perform analysis on file change.
exports.moduleRewritePlugin = ({ root, app, watcher, resolver }) => {
app.use(async (ctx, next) => {
await next();
if (ctx.status === 304) {
return;
}
// we are doing the js rewrite after all other middlewares have finished;
// this allows us to post-process javascript produced by user middlewares
// regardless of the extension of the original files.
const publicPath = ctx.path;
if (ctx.body &&
ctx.response.is('js') &&
!cssUtils_1.isCSSRequest(ctx.path) &&
!ctx.url.endsWith('.map') &&
!resolver.isPublicRequest(ctx.path) &&
// skip internal client
publicPath !== serverPluginClient_1.clientPublicPath &&
// need to rewrite for <script>\<template> part in vue files
!((ctx.path.endsWith('.vue') || ctx.vue) && ctx.query.type === 'style')) {
const content = await utils_1.readBody(ctx.body);
const cacheKey = publicPath + content;
const isHmrRequest = !!ctx.query.t;
if (!isHmrRequest && rewriteCache.has(cacheKey)) {
debug(`(cached) ${ctx.url}`);
ctx.body = rewriteCache.get(cacheKey);
}
else {
await es_module_lexer_1.init;
// dynamic import may contain extension-less path,
// (.e.g import(runtimePathString))
// so we need to normalize importer to ensure it contains extension
// before we perform hmr analysis.
// on the other hand, static import is guaranteed to have extension
// because they must all have gone through module rewrite.
const importer = utils_1.removeUnRelatedHmrQuery(resolver.normalizePublicPath(ctx.url));
ctx.body = rewriteImports(root, content, importer, resolver, ctx.query.t);
if (!isHmrRequest) {
rewriteCache.set(cacheKey, ctx.body);
}
}
}
else {
debug(`(skipped) ${ctx.url}`);
}
});
// bust module rewrite cache on file change
watcher.on('change', async (filePath) => {
const publicPath = resolver.fileToRequest(filePath);
// #662 use fs.read instead of cacheRead, avoid cache hit when request file
// and caused pass `notModified` into transform is always true
const cacheKey = publicPath + (await fs_extra_1.default.readFile(filePath)).toString();
debug(`${publicPath}: cache busted`);
rewriteCache.del(cacheKey);
});
};
function rewriteImports(root, source, importer, resolver, timestamp) {
// #806 strip UTF-8 BOM
if (source.charCodeAt(0) === 0xfeff) {
source = source.slice(1);
}
try {
let imports = [];
try {
imports = es_module_lexer_1.parse(source)[0];
}
catch (e) {
console.error(chalk_1.default.yellow(`[vite] failed to parse ${chalk_1.default.cyan(importer)} for import rewrite.\nIf you are using ` +
`JSX, make sure to named the file with the .jsx extension.`));
}
const hasHMR = source.includes('import.meta.hot');
const hasEnv = source.includes('import.meta.env');
if (imports.length || hasHMR || hasEnv) {
debug(`${importer}: rewriting`);
const s = new magic_string_1.default(source);
let hasReplaced = false;
const prevImportees = serverPluginHmr_1.importeeMap.get(importer);
const currentImportees = new Set();
serverPluginHmr_1.importeeMap.set(importer, currentImportees);
for (let i = 0; i < imports.length; i++) {
const { s: start, e: end, d: dynamicIndex } = imports[i];
let id = source.substring(start, end);
let hasLiteralDynamicId = false;
if (dynamicIndex >= 0) {
// #998 remove comment
id = id.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '');
const literalIdMatch = id.match(/^\s*(?:'([^']+)'|"([^"]+)")\s*$/);
if (literalIdMatch) {
hasLiteralDynamicId = true;
id = literalIdMatch[1] || literalIdMatch[2];
}
}
if (dynamicIndex === -1 || hasLiteralDynamicId) {
// do not rewrite external imports
if (utils_1.isExternalUrl(id)) {
continue;
}
const resolved = exports.resolveImport(root, importer, id, resolver, timestamp);
if (resolved !== id) {
debug(` "${id}" --> "${resolved}"`);
s.overwrite(start, end, hasLiteralDynamicId ? `'${resolved}'` : resolved);
hasReplaced = true;
}
// save the import chain for hmr analysis
const importee = utils_1.cleanUrl(resolved);
if (importee !== importer &&
// no need to track hmr client or module dependencies
importee !== serverPluginClient_1.clientPublicPath) {
currentImportees.add(importee);
serverPluginHmr_1.debugHmr(` ${importer} imports ${importee}`);
serverPluginHmr_1.ensureMapEntry(serverPluginHmr_1.importerMap, importee).add(importer);
}
}
else if (id !== 'import.meta' &&
!/\/\*\s*@vite-ignore\s*\*\//.test(id)) {
console.warn(chalk_1.default.yellow(`[vite] ignored dynamic import(${id}) in ${importer}.`));
}
}
if (hasHMR) {
serverPluginHmr_1.debugHmr(`rewriting ${importer} for HMR.`);
serverPluginHmr_1.rewriteFileWithHMR(root, source, importer, resolver, s);
hasReplaced = true;
}
if (hasEnv) {
debug(` injecting import.meta.env for ${importer}`);
s.prepend(`import __VITE_ENV__ from "${serverPluginEnv_1.envPublicPath}"; ` +
`import.meta.env = __VITE_ENV__; `);
hasReplaced = true;
}
// since the importees may have changed due to edits,
// check if we need to remove this importer from certain importees
if (prevImportees) {
prevImportees.forEach((importee) => {
if (!currentImportees.has(importee)) {
const importers = serverPluginHmr_1.importerMap.get(importee);
if (importers) {
importers.delete(importer);
}
}
});
}
if (!hasReplaced) {
debug(` nothing needs rewriting.`);
}
return hasReplaced ? s.toString() : source;
}
else {
debug(`${importer}: no imports found.`);
}
return source;
}
catch (e) {
console.error(`[vite] Error: module imports rewrite failed for ${importer}.\n`, e);
debug(source);
return source;
}
}
exports.rewriteImports = rewriteImports;
exports.resolveImport = (root, importer, id, resolver, timestamp) => {
id = resolver.alias(id) || id;
if (utils_1.bareImportRE.test(id)) {
// directly resolve bare module names to its entry path so that relative
// imports from it (including source map urls) can work correctly
id = `/@modules/${resolver_1.resolveBareModuleRequest(root, id, importer, resolver)}`;
}
else {
// 1. relative to absolute
// ./foo -> /some/path/foo
let { pathname, query } = resolver.resolveRelativeRequest(importer, id);
// 2. resolve dir index and extensions.
pathname = resolver.normalizePublicPath(pathname);
// 3. mark non-src imports
if (!query && path_1.default.extname(pathname) && !resolver_1.jsSrcRE.test(pathname)) {
query += `?import`;
}
id = pathname + query;
}
// 4. force re-fetch dirty imports by appending timestamp
if (timestamp) {
const dirtyFiles = serverPluginHmr_1.hmrDirtyFilesMap.get(timestamp);
const cleanId = utils_1.cleanUrl(id);
// only rewrite if:
if (dirtyFiles && dirtyFiles.has(cleanId)) {
// 1. this is a marked dirty file (in the import chain of the changed file)
id += `${id.includes(`?`) ? `&` : `?`}t=${timestamp}`;
}
else if (serverPluginHmr_1.latestVersionsMap.has(cleanId)) {
// 2. this file was previously hot-updated and has an updated version
id += `${id.includes(`?`) ? `&` : `?`}t=${serverPluginHmr_1.latestVersionsMap.get(cleanId)}`;
}
}
return id;
};
//# sourceMappingURL=serverPluginModuleRewrite.js.map