1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | var __rest = (this && this.__rest) || function (s, e) {
|
12 | var t = {};
|
13 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
14 | t[p] = s[p];
|
15 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
16 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
17 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
18 | t[p[i]] = s[p[i]];
|
19 | }
|
20 | return t;
|
21 | };
|
22 | Object.defineProperty(exports, "__esModule", { value: true });
|
23 | exports.customizeChain = void 0;
|
24 | const helper_1 = require("@tarojs/helper");
|
25 | const detectPort = require("detect-port");
|
26 | const path = require("path");
|
27 | const url_1 = require("url");
|
28 | const webpack = require("webpack");
|
29 | const WebpackDevServer = require("webpack-dev-server");
|
30 | const build_conf_1 = require("./config/build.conf");
|
31 | const dev_conf_1 = require("./config/dev.conf");
|
32 | const devServer_conf_1 = require("./config/devServer.conf");
|
33 | const prod_conf_1 = require("./config/prod.conf");
|
34 | const utils_1 = require("./utils");
|
35 | const chain_1 = require("./utils/chain");
|
36 | const logHelper_1 = require("./utils/logHelper");
|
37 | const customizeChain = (chain, modifyWebpackChainFunc, customizeFunc) => __awaiter(void 0, void 0, void 0, function* () {
|
38 | if (modifyWebpackChainFunc instanceof Function) {
|
39 | yield modifyWebpackChainFunc(chain, webpack);
|
40 | }
|
41 | if (customizeFunc instanceof Function) {
|
42 | customizeFunc(chain, webpack);
|
43 | }
|
44 | });
|
45 | exports.customizeChain = customizeChain;
|
46 | const buildProd = (appPath, config, appHelper) => __awaiter(void 0, void 0, void 0, function* () {
|
47 | const webpackChain = (0, prod_conf_1.default)(appPath, config, appHelper);
|
48 | yield (0, exports.customizeChain)(webpackChain, config.modifyWebpackChain, config.webpackChain);
|
49 | if (typeof config.onWebpackChainReady === 'function') {
|
50 | config.onWebpackChainReady(webpackChain);
|
51 | }
|
52 | const webpackConfig = webpackChain.toConfig();
|
53 | const compiler = webpack(webpackConfig);
|
54 | const onBuildFinish = config.onBuildFinish;
|
55 | compiler.hooks.emit.tapAsync('taroBuildDone', (compilation, callback) => __awaiter(void 0, void 0, void 0, function* () {
|
56 | if (typeof config.modifyBuildAssets === 'function') {
|
57 | yield config.modifyBuildAssets(compilation.assets);
|
58 | }
|
59 | callback();
|
60 | }));
|
61 | return new Promise((resolve, reject) => {
|
62 | (0, logHelper_1.bindProdLogger)(compiler);
|
63 | compiler.run((err, stats) => {
|
64 | if (err) {
|
65 | (0, logHelper_1.printBuildError)(err);
|
66 | if (typeof onBuildFinish === 'function') {
|
67 | onBuildFinish({
|
68 | error: err,
|
69 | stats: null,
|
70 | isWatch: false
|
71 | });
|
72 | }
|
73 | return reject(err);
|
74 | }
|
75 | if (typeof onBuildFinish === 'function') {
|
76 | onBuildFinish({
|
77 | error: err,
|
78 | stats,
|
79 | isWatch: false
|
80 | });
|
81 | }
|
82 | resolve();
|
83 | });
|
84 | });
|
85 | });
|
86 | const buildDev = (appPath, config, appHelper) => __awaiter(void 0, void 0, void 0, function* () {
|
87 | var _a;
|
88 | const conf = (0, build_conf_1.default)(config);
|
89 | const routerConfig = config.router || {};
|
90 | const routerMode = routerConfig.mode || 'hash';
|
91 | const routerBasename = routerConfig.basename || '/';
|
92 | const publicPath = (0, utils_1.parsePublicPath)(conf.publicPath);
|
93 | const outputPath = path.join(appPath, conf.outputRoot);
|
94 | const _b = config.devServer || {}, { proxy: customProxy = [] } = _b, customDevServerOption = __rest(_b, ["proxy"]);
|
95 | const webpackChain = (0, dev_conf_1.default)(appPath, config, appHelper);
|
96 | const onBuildFinish = config.onBuildFinish;
|
97 | yield (0, exports.customizeChain)(webpackChain, config.modifyWebpackChain, config.webpackChain);
|
98 | const isMultiRouterMode = routerMode === 'multi';
|
99 | const proxy = [];
|
100 | if (isMultiRouterMode) {
|
101 | const customRoutes = (routerConfig === null || routerConfig === void 0 ? void 0 : routerConfig.customRoutes) || {};
|
102 | const routerBasename = routerConfig.basename || '/';
|
103 | const getEntriesRoutes = (customRoutes = {}) => {
|
104 | const conf = [];
|
105 | for (let key in customRoutes) {
|
106 | const path = customRoutes[key];
|
107 | key = (0, utils_1.addLeadingSlash)(key);
|
108 | if (typeof path === 'string') {
|
109 | conf.push([key, (0, utils_1.addLeadingSlash)(path)]);
|
110 | }
|
111 | else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
|
112 | conf.push(...path.map(p => [key, (0, utils_1.addLeadingSlash)(p)]));
|
113 | }
|
114 | }
|
115 | return conf;
|
116 | };
|
117 | const bypass = req => {
|
118 | var _a, _b, _c, _d;
|
119 | if (((_a = req.headers.accept) === null || _a === void 0 ? void 0 : _a.indexOf('html')) !== -1) {
|
120 | const pagePath = (0, utils_1.stripTrailingSlash)((0, utils_1.stripBasename)(req.path, routerBasename));
|
121 | if (pagePath === '') {
|
122 | return (0, utils_1.addHtmlSuffix)(appHelper.appConfig.entryPagePath || ((_b = appHelper.appConfig.pages) === null || _b === void 0 ? void 0 : _b[0]));
|
123 | }
|
124 | const pageIdx = ((_c = appHelper.appConfig.pages) !== null && _c !== void 0 ? _c : []).findIndex(e => (0, utils_1.addLeadingSlash)(e) === pagePath);
|
125 | if (pageIdx > -1) {
|
126 | return (0, utils_1.addHtmlSuffix)((_d = appHelper.appConfig.pages) === null || _d === void 0 ? void 0 : _d[pageIdx]);
|
127 | }
|
128 | const customRoutesConf = getEntriesRoutes(customRoutes);
|
129 | const idx = getEntriesRoutes(customRoutes).findIndex(list => list[1] === pagePath);
|
130 | if (idx > -1) {
|
131 |
|
132 | return (0, utils_1.addHtmlSuffix)(customRoutesConf[idx][0]);
|
133 | }
|
134 | }
|
135 | };
|
136 | proxy.push({
|
137 | context: [routerBasename],
|
138 | bypass
|
139 | });
|
140 | }
|
141 | if (!(customProxy instanceof Array)) {
|
142 | proxy.push(...Object.entries(customProxy).map(([url, options = {}]) => {
|
143 | const item = {
|
144 | context: [url]
|
145 | };
|
146 | if (typeof options === 'string') {
|
147 | item.target = options;
|
148 | }
|
149 | else {
|
150 | Object.assign(item, options);
|
151 | }
|
152 | return item;
|
153 | }));
|
154 | }
|
155 | if (typeof config.onWebpackChainReady === 'function') {
|
156 | config.onWebpackChainReady(webpackChain);
|
157 | }
|
158 | const devServerOptions = config.isBuildNativeComp
|
159 | ? { writeToDisk: true }
|
160 | : (0, helper_1.recursiveMerge)({
|
161 | publicPath,
|
162 | contentBase: outputPath,
|
163 | historyApiFallback: {
|
164 | rewrites: [{
|
165 | from: /./,
|
166 | to: publicPath
|
167 | }]
|
168 | },
|
169 | proxy,
|
170 | }, devServer_conf_1.default, customDevServerOption);
|
171 | if (((_a = devServerOptions.proxy) === null || _a === void 0 ? void 0 : _a.length) < 1) {
|
172 |
|
173 | delete devServerOptions.proxy;
|
174 | }
|
175 | if (devServerOptions.host === 'localhost') {
|
176 | devServerOptions.useLocalIp = false;
|
177 | }
|
178 | const originalPort = Number(devServerOptions.port);
|
179 | const availablePort = yield detectPort(originalPort);
|
180 | if (availablePort !== originalPort) {
|
181 | console.log();
|
182 | console.log(`预览端口 ${originalPort} 被占用, 自动切换到空闲端口 ${availablePort}`);
|
183 | devServerOptions.port = availablePort;
|
184 | }
|
185 | let pathname;
|
186 | if (routerMode === 'multi') {
|
187 | pathname = '/';
|
188 | }
|
189 | else if (routerMode === 'browser') {
|
190 | pathname = routerBasename;
|
191 | }
|
192 | else {
|
193 | pathname = '/';
|
194 | }
|
195 | const devUrl = (0, url_1.format)({
|
196 | protocol: devServerOptions.https ? 'https' : 'http',
|
197 | hostname: (0, utils_1.formatOpenHost)(devServerOptions.host),
|
198 | port: devServerOptions.port,
|
199 | pathname
|
200 | });
|
201 | const webpackConfig = webpackChain.toConfig();
|
202 | WebpackDevServer.addDevServerEntrypoints(webpackConfig, devServerOptions);
|
203 | const compiler = webpack(webpackConfig);
|
204 | (0, logHelper_1.bindDevLogger)(compiler, devUrl);
|
205 | const server = new WebpackDevServer(compiler, devServerOptions);
|
206 | compiler.hooks.emit.tapAsync('taroBuildDone', (compilation, callback) => __awaiter(void 0, void 0, void 0, function* () {
|
207 | if (typeof config.modifyBuildAssets === 'function') {
|
208 | yield config.modifyBuildAssets(compilation.assets);
|
209 | }
|
210 | callback();
|
211 | }));
|
212 | compiler.hooks.done.tap('taroBuildDone', stats => {
|
213 | if (typeof onBuildFinish === 'function') {
|
214 | onBuildFinish({
|
215 | error: null,
|
216 | stats,
|
217 | isWatch: true
|
218 | });
|
219 | }
|
220 | });
|
221 | compiler.hooks.failed.tap('taroBuildDone', error => {
|
222 | if (typeof onBuildFinish === 'function') {
|
223 | onBuildFinish({
|
224 | error,
|
225 | stats: null,
|
226 | isWatch: true
|
227 | });
|
228 | }
|
229 | });
|
230 | return new Promise((resolve, reject) => {
|
231 | server.listen(devServerOptions.port, devServerOptions.host, err => {
|
232 | if (err) {
|
233 | reject(err);
|
234 | return console.log(err);
|
235 | }
|
236 | resolve();
|
237 | });
|
238 | });
|
239 | });
|
240 | exports.default = (appPath, config) => __awaiter(void 0, void 0, void 0, function* () {
|
241 | const newConfig = yield (0, chain_1.makeConfig)(config);
|
242 | const app = new utils_1.AppHelper(newConfig.entry, {
|
243 | sourceDir: path.join(appPath, config.sourceRoot || helper_1.SOURCE_DIR),
|
244 | frameworkExts: newConfig.frameworkExts,
|
245 | entryFileName: newConfig.entryFileName
|
246 | });
|
247 | if (newConfig.isWatch) {
|
248 | try {
|
249 | yield buildDev(appPath, newConfig, app);
|
250 | }
|
251 | catch (e) {
|
252 | console.error(e);
|
253 | }
|
254 | }
|
255 | else {
|
256 | try {
|
257 | yield buildProd(appPath, newConfig, app);
|
258 | }
|
259 | catch (e) {
|
260 | console.error(e);
|
261 | process.exit(1);
|
262 | }
|
263 | }
|
264 | });
|
265 |
|
\ | No newline at end of file |