UNPKG

11.1 kBJavaScriptView Raw
1"use strict";
2var __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};
11var __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};
22Object.defineProperty(exports, "__esModule", { value: true });
23exports.customizeChain = void 0;
24const helper_1 = require("@tarojs/helper");
25const detectPort = require("detect-port");
26const path = require("path");
27const url_1 = require("url");
28const webpack = require("webpack");
29const WebpackDevServer = require("webpack-dev-server");
30const build_conf_1 = require("./config/build.conf");
31const dev_conf_1 = require("./config/dev.conf");
32const devServer_conf_1 = require("./config/devServer.conf");
33const prod_conf_1 = require("./config/prod.conf");
34const utils_1 = require("./utils");
35const chain_1 = require("./utils/chain");
36const logHelper_1 = require("./utils/logHelper");
37const 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});
45exports.customizeChain = customizeChain;
46const 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});
86const 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 // NOTE: 自定义路由
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 // Note: proxy 不可以为空数组
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});
240exports.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//# sourceMappingURL=index.js.map
\No newline at end of file