mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-08 09:27:19 +08:00
220 lines
10 KiB
JavaScript
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
|