UNPKG

fuse-box

Version:

Fuse-Box a bundler that does it right

141 lines (140 loc) 6.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createBundle = exports.BundleType = void 0; const CleanCSS = require("clean-css"); const convertSourceMap = require("convert-source-map"); const offsetLinesModule = require("offset-sourcemap-lines"); const path = require("path"); const Terser = require("terser"); const bundleSource_1 = require("../bundleRuntime/bundleSource"); const distWriter_1 = require("../output/distWriter"); var BundleType; (function (BundleType) { BundleType[BundleType["CSS_APP"] = 1] = "CSS_APP"; BundleType[BundleType["CSS_SPLIT"] = 2] = "CSS_SPLIT"; BundleType[BundleType["JS_APP"] = 3] = "JS_APP"; BundleType[BundleType["JS_SERVER_ENTRY"] = 4] = "JS_SERVER_ENTRY"; BundleType[BundleType["JS_SPLIT"] = 5] = "JS_SPLIT"; BundleType[BundleType["JS_VENDOR"] = 6] = "JS_VENDOR"; })(BundleType = exports.BundleType || (exports.BundleType = {})); function createBundle(props) { const { bundleConfig, ctx, priority, type, webIndexed = true } = props; const outputConfig = ctx.outputConfig; const isProduction = ctx.config.isProduction; const target = ctx.config.target; const bundleWriter = distWriter_1.distWriter({ hashEnabled: isProduction, root: outputConfig.distRoot }); const isCSS = type === BundleType.CSS_APP || type === BundleType.CSS_SPLIT; const source = bundleSource_1.createBundleSource({ isCSS: isCSS, isProduction: props.ctx.config.isProduction, target, }); const shouldCleanCSS = !!ctx.config.cleanCSS; function optimizeCSS(self) { let userProps = {}; if (typeof ctx.config.cleanCSS === 'object') userProps = ctx.config.cleanCSS; const response = new CleanCSS(Object.assign(Object.assign({}, userProps), { sourceMap: source.containsMaps, sourceMapInlineSources: true })).minify(self.data.content.toString(), self.data.sourceMap); self.data = { sourceMap: response.sourceMap, content: response.styles }; } const self = { config: null, contents: null, data: null, isCSSType: isCSS, priority, source, type, webIndexed, createSourceMap: async (sourceMap) => { const sourceMapName = path.basename(self.config.relativePath) + '.map'; if (isCSS) { // just in case remove the existing sourcemap references // some css preprocessors add it self.contents = self.contents.replace(/\/\*\#\s?sourceMappingURL.*?\*\//g, ''); self.contents += `\n/*# sourceMappingURL=${sourceMapName} */`; } else { self.contents += `\n//# sourceMappingURL=${sourceMapName}`; } const targetDir = path.dirname(self.config.absPath); const sourceMapFile = path.join(targetDir, sourceMapName); await bundleWriter.write(sourceMapFile, sourceMap); }, generate: async (opts) => { opts = opts || {}; if (!self.config) self.prepare(); if (self.entries) { source.entries = self.entries; if (self.exported) source.exported = true; } ctx.ict.sync('before_bundle_write', { bundle: self }); self.data = source.generate({ isIsolated: bundleConfig.isolatedApi, runtimeCore: opts.runtimeCore }); if (isCSS && shouldCleanCSS) optimizeCSS(self); self.contents = self.data.content.toString(); let sourceMap; if (source.containsMaps && self.data.sourceMap) { sourceMap = self.data.sourceMap.toString(); } if (ctx.config.isProduction && !self.isCSSType && opts.uglify) { const terserOpts = { sourceMap: source.containsMaps ? { content: self.data.sourceMap, includeSources: true, } : undefined, }; ctx.log.info('minify', self.config.absPath); const result = await Terser.minify(self.contents, terserOpts); self.contents = result.code; if (source.containsMaps && result.map) { sourceMap = result.map.toString(); } } // writing source maps if (source.containsMaps) await self.createSourceMap(sourceMap); // write the bundle to fs return await self.write(); }, generateHMRUpdate: () => { const concat = source.generate({ isIsolated: false, runtimeCore: undefined }); const rawSourceMap = concat.sourceMap; let stringContent = concat.content.toString(); if (self.source.containsMaps) { if (rawSourceMap) { let json = JSON.parse(rawSourceMap); // since new Function wrapoer adds extra 2 lines we need to shift sourcemaps json = offsetLinesModule(json, 2); const sm = convertSourceMap.fromObject(json).toComment(); stringContent += '\n' + sm; } } return stringContent; }, prepare: () => { self.config = bundleWriter.createWriter({ fileName: props.fileName, hash: isProduction && self.source.generateHash(), publicPath: bundleConfig.publicPath, userString: bundleConfig.path, }); return self.config; }, write: async () => { await bundleWriter.write(self.config.absPath, self.contents); return { absPath: self.config.absPath, browserPath: self.config.browserPath, bundle: self, relativePath: self.config.relativePath, }; }, }; return self; } exports.createBundle = createBundle;