2021-03-01 15:06:11 +08:00

165 lines
6.8 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.codegenCss = exports.cssPlugin = exports.debugCSS = void 0;
const path_1 = require("path");
const hash_sum_1 = __importDefault(require("hash-sum"));
const utils_1 = require("../utils");
const serverPluginVue_1 = require("./serverPluginVue");
const cssUtils_1 = require("../utils/cssUtils");
const querystring_1 = __importDefault(require("querystring"));
const chalk_1 = __importDefault(require("chalk"));
const serverPluginClient_1 = require("./serverPluginClient");
const pluginutils_1 = require("@rollup/pluginutils");
exports.debugCSS = require('debug')('vite:css');
exports.cssPlugin = ({ root, app, watcher, resolver }) => {
app.use(async (ctx, next) => {
await next();
// handle .css imports
if (cssUtils_1.isCSSRequest(ctx.path) &&
// note ctx.body could be null if upstream set status to 304
ctx.body) {
const id = JSON.stringify(hash_sum_1.default(ctx.path));
if (utils_1.isImportRequest(ctx)) {
const { css, modules } = await processCss(root, ctx);
ctx.type = 'js';
// we rewrite css with `?import` to a js module that inserts a style
// tag linking to the actual raw url
ctx.body = codegenCss(id, css, modules);
}
}
});
watcher.on('change', (filePath) => {
if (cssUtils_1.isCSSRequest(filePath)) {
const publicPath = resolver.fileToRequest(filePath);
/** filter unused files */
if (!cssUtils_1.cssImporterMap.has(filePath) &&
!processedCSS.has(publicPath) &&
!serverPluginVue_1.srcImportMap.has(filePath)) {
return exports.debugCSS(`${path_1.basename(publicPath)} has changed, but it is not currently in use`);
}
if (serverPluginVue_1.srcImportMap.has(filePath)) {
// handle HMR for <style src="xxx.css">
// it cannot be handled as simple css import because it may be scoped
const styleImport = serverPluginVue_1.srcImportMap.get(filePath);
serverPluginVue_1.vueCache.del(filePath);
vueStyleUpdate(styleImport);
return;
}
// handle HMR for module css
// it cannot be handled as normal css because the js exports may change
if (filePath.includes('.module')) {
moduleCssUpdate(filePath, resolver);
}
const boundaries = cssUtils_1.getCssImportBoundaries(filePath);
if (boundaries.size) {
boundaryCssUpdate(boundaries);
return;
}
// no boundaries
normalCssUpdate(publicPath);
}
else if (cssUtils_1.cssImporterMap.has(filePath)) {
const boundaries = cssUtils_1.getCssImportBoundaries(filePath);
if (boundaries.size) {
boundaryCssUpdate(boundaries);
}
}
});
function boundaryCssUpdate(boundaries) {
for (let boundary of boundaries) {
if (boundary.includes('.module')) {
moduleCssUpdate(boundary, resolver);
}
else if (boundary.includes('.vue')) {
serverPluginVue_1.vueCache.del(utils_1.cleanUrl(boundary));
vueStyleUpdate(resolver.fileToRequest(boundary));
}
else {
normalCssUpdate(resolver.fileToRequest(boundary));
}
}
}
function vueStyleUpdate(styleImport) {
const publicPath = utils_1.cleanUrl(styleImport);
const index = querystring_1.default.parse(styleImport.split('?', 2)[1]).index;
const path = `${publicPath}?type=style&index=${index}`;
console.log(chalk_1.default.green(`[vite:hmr] `) + `${publicPath} updated. (style)`);
watcher.send({
type: 'style-update',
path,
changeSrcPath: path,
timestamp: Date.now()
});
}
function moduleCssUpdate(filePath, resolver) {
// bust process cache
processedCSS.delete(resolver.fileToRequest(filePath));
watcher.handleJSReload(filePath);
}
function normalCssUpdate(publicPath) {
// bust process cache
processedCSS.delete(publicPath);
watcher.send({
type: 'style-update',
path: publicPath,
changeSrcPath: publicPath,
timestamp: Date.now()
});
}
// processed CSS is cached in case the user ticks "disable cache" during dev
// which can lead to unnecessary processing on page reload
const processedCSS = new Map();
async function processCss(root, ctx) {
// source didn't change (marker added by cachedRead)
// just use previously cached result
if (ctx.__notModified && processedCSS.has(ctx.path)) {
return processedCSS.get(ctx.path);
}
const css = (await utils_1.readBody(ctx.body));
const filePath = resolver.requestToFile(ctx.path);
const preprocessLang = (ctx.path.match(cssUtils_1.cssPreprocessLangRE) || [])[1];
const result = await cssUtils_1.compileCss(root, ctx.path, {
id: '',
source: css,
filename: filePath,
scoped: false,
modules: ctx.path.includes('.module'),
preprocessLang,
preprocessOptions: ctx.config.cssPreprocessOptions,
modulesOptions: ctx.config.cssModuleOptions
});
if (typeof result === 'string') {
const res = { css: await cssUtils_1.rewriteCssUrls(css, ctx.path) };
processedCSS.set(ctx.path, res);
return res;
}
cssUtils_1.recordCssImportChain(result.dependencies, filePath);
if (result.errors.length) {
console.error(`[vite] error applying css transforms: `);
result.errors.forEach(console.error);
}
const res = {
css: await cssUtils_1.rewriteCssUrls(result.code, ctx.path),
modules: result.modules
};
processedCSS.set(ctx.path, res);
return res;
}
};
function codegenCss(id, css, modules) {
let code = `import { updateStyle } from "${serverPluginClient_1.clientPublicPath}"\n` +
`const css = ${JSON.stringify(css)}\n` +
`updateStyle(${JSON.stringify(id)}, css)\n`;
if (modules) {
code += pluginutils_1.dataToEsm(modules, { namedExports: true });
}
else {
code += `export default css`;
}
return code;
}
exports.codegenCss = codegenCss;
//# sourceMappingURL=serverPluginCss.js.map