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 | Object.defineProperty(exports, "__esModule", { value: true });
|
12 | const detectPort = require("detect-port");
|
13 | const path = require("path");
|
14 | const url_1 = require("url");
|
15 | const webpack = require("webpack");
|
16 | const WebpackDevServer = require("webpack-dev-server");
|
17 | const helper_1 = require("@tarojs/helper");
|
18 | const build_conf_1 = require("./config/build.conf");
|
19 | const dev_conf_1 = require("./config/dev.conf");
|
20 | const devServer_conf_1 = require("./config/devServer.conf");
|
21 | const prod_conf_1 = require("./config/prod.conf");
|
22 | const util_1 = require("./util");
|
23 | const logHelper_1 = require("./util/logHelper");
|
24 | const chain_1 = require("./util/chain");
|
25 | exports.customizeChain = (chain, modifyWebpackChainFunc, customizeFunc) => __awaiter(void 0, void 0, void 0, function* () {
|
26 | if (modifyWebpackChainFunc instanceof Function) {
|
27 | yield modifyWebpackChainFunc(chain, webpack);
|
28 | }
|
29 | if (customizeFunc instanceof Function) {
|
30 | customizeFunc(chain, webpack);
|
31 | }
|
32 | });
|
33 | const buildProd = (appPath, config) => __awaiter(void 0, void 0, void 0, function* () {
|
34 | const webpackChain = prod_conf_1.default(appPath, config);
|
35 | yield exports.customizeChain(webpackChain, config.modifyWebpackChain, config.webpackChain);
|
36 | if (typeof config.onWebpackChainReady === 'function') {
|
37 | config.onWebpackChainReady(webpackChain);
|
38 | }
|
39 | const webpackConfig = webpackChain.toConfig();
|
40 | const compiler = webpack(webpackConfig);
|
41 | const onBuildFinish = config.onBuildFinish;
|
42 | compiler.hooks.emit.tapAsync('taroBuildDone', (compilation, callback) => __awaiter(void 0, void 0, void 0, function* () {
|
43 | if (typeof config.modifyBuildAssets === 'function') {
|
44 | yield config.modifyBuildAssets(compilation.assets);
|
45 | }
|
46 | callback();
|
47 | }));
|
48 | return new Promise((resolve, reject) => {
|
49 | logHelper_1.bindProdLogger(compiler);
|
50 | compiler.run((err, stats) => {
|
51 | if (err) {
|
52 | logHelper_1.printBuildError(err);
|
53 | if (typeof onBuildFinish === 'function') {
|
54 | onBuildFinish({
|
55 | error: err,
|
56 | stats: null,
|
57 | isWatch: false
|
58 | });
|
59 | }
|
60 | return reject(err);
|
61 | }
|
62 | if (typeof onBuildFinish === 'function') {
|
63 | onBuildFinish({
|
64 | error: err,
|
65 | stats,
|
66 | isWatch: false
|
67 | });
|
68 | }
|
69 | resolve();
|
70 | });
|
71 | });
|
72 | });
|
73 | const buildDev = (appPath, config) => __awaiter(void 0, void 0, void 0, function* () {
|
74 | const conf = build_conf_1.default(config);
|
75 | const routerConfig = config.router || {};
|
76 | const routerMode = routerConfig.mode || 'hash';
|
77 | const routerBasename = routerConfig.basename || '/';
|
78 | const publicPath = conf.publicPath ? util_1.addLeadingSlash(util_1.addTrailingSlash(conf.publicPath)) : '/';
|
79 | const outputPath = path.join(appPath, conf.outputRoot);
|
80 | const customDevServerOption = config.devServer || {};
|
81 | const webpackChain = dev_conf_1.default(appPath, config);
|
82 | const onBuildFinish = config.onBuildFinish;
|
83 | yield exports.customizeChain(webpackChain, config.modifyWebpackChain, config.webpackChain);
|
84 | if (typeof config.onWebpackChainReady === 'function') {
|
85 | config.onWebpackChainReady(webpackChain);
|
86 | }
|
87 | const devServerOptions = helper_1.recursiveMerge({
|
88 | publicPath,
|
89 | contentBase: outputPath,
|
90 | historyApiFallback: {
|
91 | rewrites: [{
|
92 | from: /./,
|
93 | to: publicPath
|
94 | }]
|
95 | }
|
96 | }, devServer_conf_1.default, customDevServerOption);
|
97 | const originalPort = devServerOptions.port;
|
98 | const availablePort = yield detectPort(originalPort);
|
99 | if (availablePort !== originalPort) {
|
100 | console.log();
|
101 | console.log(`预览端口 ${originalPort} 被占用, 自动切换到空闲端口 ${availablePort}`);
|
102 | devServerOptions.port = availablePort;
|
103 | }
|
104 | let pathname;
|
105 | if (routerMode === 'multi') {
|
106 | pathname = '/';
|
107 | }
|
108 | else if (routerMode === 'browser') {
|
109 | pathname = routerBasename;
|
110 | }
|
111 | else {
|
112 | pathname = '/';
|
113 | }
|
114 | const devUrl = url_1.format({
|
115 | protocol: devServerOptions.https ? 'https' : 'http',
|
116 | hostname: devServerOptions.host,
|
117 | port: devServerOptions.port,
|
118 | pathname
|
119 | });
|
120 | const webpackConfig = webpackChain.toConfig();
|
121 | WebpackDevServer.addDevServerEntrypoints(webpackConfig, devServerOptions);
|
122 | const compiler = webpack(webpackConfig);
|
123 | logHelper_1.bindDevLogger(devUrl, compiler);
|
124 | const server = new WebpackDevServer(compiler, devServerOptions);
|
125 | compiler.hooks.emit.tapAsync('taroBuildDone', (compilation, callback) => __awaiter(void 0, void 0, void 0, function* () {
|
126 | if (typeof config.modifyBuildAssets === 'function') {
|
127 | yield config.modifyBuildAssets(compilation.assets);
|
128 | }
|
129 | callback();
|
130 | }));
|
131 | compiler.hooks.done.tap('taroBuildDone', stats => {
|
132 | if (typeof onBuildFinish === 'function') {
|
133 | onBuildFinish({
|
134 | error: null,
|
135 | stats,
|
136 | isWatch: true
|
137 | });
|
138 | }
|
139 | });
|
140 | compiler.hooks.failed.tap('taroBuildDone', error => {
|
141 | if (typeof onBuildFinish === 'function') {
|
142 | onBuildFinish({
|
143 | error,
|
144 | stats: null,
|
145 | isWatch: true
|
146 | });
|
147 | }
|
148 | });
|
149 | return new Promise((resolve, reject) => {
|
150 | server.listen(devServerOptions.port, devServerOptions.host, err => {
|
151 | if (err) {
|
152 | reject(err);
|
153 | return console.log(err);
|
154 | }
|
155 | resolve();
|
156 |
|
157 | if (devServerOptions.open) {
|
158 | const openUrl = url_1.format({
|
159 | protocol: devServerOptions.https ? 'https' : 'http',
|
160 | hostname: util_1.formatOpenHost(devServerOptions.host),
|
161 | port: devServerOptions.port,
|
162 | pathname
|
163 | });
|
164 | console.log(openUrl);
|
165 | }
|
166 | });
|
167 | });
|
168 | });
|
169 | exports.default = (appPath, config) => __awaiter(void 0, void 0, void 0, function* () {
|
170 | const newConfig = yield chain_1.makeConfig(config);
|
171 | if (newConfig.isWatch) {
|
172 | try {
|
173 | yield buildDev(appPath, newConfig);
|
174 | }
|
175 | catch (e) {
|
176 | console.error(e);
|
177 | }
|
178 | }
|
179 | else {
|
180 | try {
|
181 | yield buildProd(appPath, newConfig);
|
182 | }
|
183 | catch (e) {
|
184 | console.error(e);
|
185 | process.exit(1);
|
186 | }
|
187 | }
|
188 | });
|
189 |
|
\ | No newline at end of file |