UNPKG

@tarojs/webpack-runner

Version:

webpack runner for taro

265 lines 11.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.customizeChain = void 0; const helper_1 = require("@tarojs/helper"); const detectPort = require("detect-port"); const path = require("path"); const url_1 = require("url"); const webpack = require("webpack"); const WebpackDevServer = require("webpack-dev-server"); const build_conf_1 = require("./config/build.conf"); const dev_conf_1 = require("./config/dev.conf"); const devServer_conf_1 = require("./config/devServer.conf"); const prod_conf_1 = require("./config/prod.conf"); const utils_1 = require("./utils"); const chain_1 = require("./utils/chain"); const logHelper_1 = require("./utils/logHelper"); const customizeChain = (chain, modifyWebpackChainFunc, customizeFunc) => __awaiter(void 0, void 0, void 0, function* () { if (modifyWebpackChainFunc instanceof Function) { yield modifyWebpackChainFunc(chain, webpack); } if (customizeFunc instanceof Function) { customizeFunc(chain, webpack); } }); exports.customizeChain = customizeChain; const buildProd = (appPath, config, appHelper) => __awaiter(void 0, void 0, void 0, function* () { const webpackChain = (0, prod_conf_1.default)(appPath, config, appHelper); yield (0, exports.customizeChain)(webpackChain, config.modifyWebpackChain, config.webpackChain); if (typeof config.onWebpackChainReady === 'function') { config.onWebpackChainReady(webpackChain); } const webpackConfig = webpackChain.toConfig(); const compiler = webpack(webpackConfig); const onBuildFinish = config.onBuildFinish; compiler.hooks.emit.tapAsync('taroBuildDone', (compilation, callback) => __awaiter(void 0, void 0, void 0, function* () { if (typeof config.modifyBuildAssets === 'function') { yield config.modifyBuildAssets(compilation.assets); } callback(); })); return new Promise((resolve, reject) => { (0, logHelper_1.bindProdLogger)(compiler); compiler.run((err, stats) => { if (err) { (0, logHelper_1.printBuildError)(err); if (typeof onBuildFinish === 'function') { onBuildFinish({ error: err, stats: null, isWatch: false }); } return reject(err); } if (typeof onBuildFinish === 'function') { onBuildFinish({ error: err, stats, isWatch: false }); } resolve(); }); }); }); const buildDev = (appPath, config, appHelper) => __awaiter(void 0, void 0, void 0, function* () { var _a; const conf = (0, build_conf_1.default)(config); const routerConfig = config.router || {}; const routerMode = routerConfig.mode || 'hash'; const routerBasename = routerConfig.basename || '/'; const publicPath = (0, utils_1.parsePublicPath)(conf.publicPath); const outputPath = path.join(appPath, conf.outputRoot); const _b = config.devServer || {}, { proxy: customProxy = [] } = _b, customDevServerOption = __rest(_b, ["proxy"]); const webpackChain = (0, dev_conf_1.default)(appPath, config, appHelper); const onBuildFinish = config.onBuildFinish; yield (0, exports.customizeChain)(webpackChain, config.modifyWebpackChain, config.webpackChain); const isMultiRouterMode = routerMode === 'multi'; const proxy = []; if (isMultiRouterMode) { const customRoutes = (routerConfig === null || routerConfig === void 0 ? void 0 : routerConfig.customRoutes) || {}; const routerBasename = routerConfig.basename || '/'; const getEntriesRoutes = (customRoutes = {}) => { const conf = []; for (let key in customRoutes) { const path = customRoutes[key]; key = (0, utils_1.addLeadingSlash)(key); if (typeof path === 'string') { conf.push([key, (0, utils_1.addLeadingSlash)(path)]); } else if ((path === null || path === void 0 ? void 0 : path.length) > 0) { conf.push(...path.map(p => [key, (0, utils_1.addLeadingSlash)(p)])); } } return conf; }; const bypass = req => { var _a, _b, _c, _d; if (((_a = req.headers.accept) === null || _a === void 0 ? void 0 : _a.indexOf('html')) !== -1) { const pagePath = (0, utils_1.stripTrailingSlash)((0, utils_1.stripBasename)(req.path, routerBasename)); if (pagePath === '') { return (0, utils_1.addHtmlSuffix)(appHelper.appConfig.entryPagePath || ((_b = appHelper.appConfig.pages) === null || _b === void 0 ? void 0 : _b[0])); } const pageIdx = ((_c = appHelper.appConfig.pages) !== null && _c !== void 0 ? _c : []).findIndex(e => (0, utils_1.addLeadingSlash)(e) === pagePath); if (pageIdx > -1) { return (0, utils_1.addHtmlSuffix)((_d = appHelper.appConfig.pages) === null || _d === void 0 ? void 0 : _d[pageIdx]); } const customRoutesConf = getEntriesRoutes(customRoutes); const idx = getEntriesRoutes(customRoutes).findIndex(list => list[1] === pagePath); if (idx > -1) { // NOTE: 自定义路由 return (0, utils_1.addHtmlSuffix)(customRoutesConf[idx][0]); } } }; proxy.push({ context: [routerBasename], bypass }); } if (!(customProxy instanceof Array)) { proxy.push(...Object.entries(customProxy).map(([url, options = {}]) => { const item = { context: [url] }; if (typeof options === 'string') { item.target = options; } else { Object.assign(item, options); } return item; })); } if (typeof config.onWebpackChainReady === 'function') { config.onWebpackChainReady(webpackChain); } const devServerOptions = config.isBuildNativeComp ? { writeToDisk: true } : (0, helper_1.recursiveMerge)({ publicPath, contentBase: outputPath, historyApiFallback: { rewrites: [{ from: /./, to: publicPath }] }, proxy, }, devServer_conf_1.default, customDevServerOption); if (((_a = devServerOptions.proxy) === null || _a === void 0 ? void 0 : _a.length) < 1) { // Note: proxy 不可以为空数组 delete devServerOptions.proxy; } if (devServerOptions.host === 'localhost') { devServerOptions.useLocalIp = false; } const originalPort = Number(devServerOptions.port); const availablePort = yield detectPort(originalPort); if (availablePort !== originalPort) { console.log(); console.log(`预览端口 ${originalPort} 被占用, 自动切换到空闲端口 ${availablePort}`); devServerOptions.port = availablePort; } let pathname; if (routerMode === 'multi') { pathname = '/'; } else if (routerMode === 'browser') { pathname = routerBasename; } else { pathname = '/'; } const devUrl = (0, url_1.format)({ protocol: devServerOptions.https ? 'https' : 'http', hostname: (0, utils_1.formatOpenHost)(devServerOptions.host), port: devServerOptions.port, pathname }); const webpackConfig = webpackChain.toConfig(); WebpackDevServer.addDevServerEntrypoints(webpackConfig, devServerOptions); const compiler = webpack(webpackConfig); (0, logHelper_1.bindDevLogger)(compiler, devUrl); const server = new WebpackDevServer(compiler, devServerOptions); compiler.hooks.emit.tapAsync('taroBuildDone', (compilation, callback) => __awaiter(void 0, void 0, void 0, function* () { if (typeof config.modifyBuildAssets === 'function') { yield config.modifyBuildAssets(compilation.assets); } callback(); })); compiler.hooks.done.tap('taroBuildDone', stats => { if (typeof onBuildFinish === 'function') { onBuildFinish({ error: null, stats, isWatch: true }); } }); compiler.hooks.failed.tap('taroBuildDone', error => { if (typeof onBuildFinish === 'function') { onBuildFinish({ error, stats: null, isWatch: true }); } }); return new Promise((resolve, reject) => { server.listen(devServerOptions.port, devServerOptions.host, err => { if (err) { reject(err); return console.log(err); } resolve(); }); }); }); exports.default = (appPath, config) => __awaiter(void 0, void 0, void 0, function* () { const newConfig = yield (0, chain_1.makeConfig)(config); const app = new utils_1.AppHelper(newConfig.entry, { sourceDir: path.join(appPath, config.sourceRoot || helper_1.SOURCE_DIR), frameworkExts: newConfig.frameworkExts, entryFileName: newConfig.entryFileName }); if (newConfig.isWatch) { try { yield buildDev(appPath, newConfig, app); } catch (e) { console.error(e); } } else { try { yield buildProd(appPath, newConfig, app); } catch (e) { console.error(e); process.exit(1); } } }); //# sourceMappingURL=index.js.map