| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- "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
|