UNPKG

18.3 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.getDevtool = exports.getOutput = exports.parseModule = exports.getMainPlugin = exports.getCopyWebpackPlugin = exports.getCssoWebpackPlugin = exports.getTerserPlugin = exports.getHotModuleReplacementPlugin = exports.getDefinePlugin = exports.getHtmlWebpackPlugin = exports.getMiniCssExtractPlugin = exports.processEnvOption = exports.makeConfig = void 0;
24const helper_1 = require("@tarojs/helper");
25const runner_utils_1 = require("@tarojs/runner-utils");
26const CopyWebpackPlugin = require("copy-webpack-plugin");
27const csso_webpack_plugin_1 = require("csso-webpack-plugin");
28const HtmlWebpackPlugin = require("html-webpack-plugin");
29const lodash_1 = require("lodash");
30const fp_1 = require("lodash/fp");
31const MiniCssExtractPlugin = require("mini-css-extract-plugin");
32const path = require("path");
33const sass = require("sass");
34const TerserPlugin = require("terser-webpack-plugin");
35const webpack = require("webpack");
36const postcss_conf_1 = require("../config/postcss.conf");
37const H5Plugin_1 = require("../plugins/H5Plugin");
38const makeConfig = (buildConfig) => __awaiter(void 0, void 0, void 0, function* () {
39 const sassLoaderOption = yield (0, runner_utils_1.getSassLoaderOption)(buildConfig);
40 return Object.assign(Object.assign({}, buildConfig), { sassLoaderOption });
41});
42exports.makeConfig = makeConfig;
43const defaultTerserOption = {
44 keep_fnames: true,
45 output: {
46 comments: false,
47 keep_quoted_props: true,
48 quote_keys: true,
49 beautify: false
50 },
51 warnings: false
52};
53const defaultCSSCompressOption = {
54 mergeRules: false,
55 mergeIdents: false,
56 reduceIdents: false,
57 discardUnused: false,
58 minifySelectors: false
59};
60const defaultMediaUrlLoaderOption = {
61 limit: 10240,
62 esModule: false
63};
64const defaultFontUrlLoaderOption = {
65 limit: 10240,
66 esModule: false
67};
68const defaultImageUrlLoaderOption = {
69 limit: 10240,
70 esModule: false
71};
72const defaultCssModuleOption = {
73 enable: false,
74 config: {
75 namingPattern: 'global',
76 generateScopedName: '[name]__[local]___[hash:base64:5]'
77 }
78};
79const getLoader = (loaderName, options) => {
80 return {
81 loader: require.resolve(loaderName),
82 options: options || {}
83 };
84};
85const listify = listOrItem => {
86 if (Array.isArray(listOrItem)) {
87 return listOrItem;
88 }
89 return [listOrItem];
90};
91const getPlugin = (plugin, args) => {
92 return {
93 plugin,
94 args
95 };
96};
97const mergeOption = ([...options]) => {
98 return (0, helper_1.recursiveMerge)({}, ...options);
99};
100exports.processEnvOption = (0, lodash_1.partial)(fp_1.mapKeys, key => `process.env.${key}`);
101const getStyleLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'style-loader'));
102const getCssLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'css-loader'));
103const getPostcssLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'postcss-loader'));
104const getResolveUrlLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'resolve-url-loader'));
105const getSassLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'sass-loader'));
106const getLessLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'less-loader'));
107const getStylusLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'stylus-loader'));
108const getBabelLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'babel-loader'));
109const getUrlLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, 'url-loader'));
110const getExtractCssLoader = () => {
111 return {
112 loader: MiniCssExtractPlugin.loader
113 };
114};
115const getImportMetaLoader = (0, fp_1.pipe)(mergeOption, (0, lodash_1.partial)(getLoader, '@open-wc/webpack-import-meta-loader'));
116exports.getMiniCssExtractPlugin = (0, fp_1.pipe)(mergeOption, listify, (0, lodash_1.partial)(getPlugin, MiniCssExtractPlugin));
117exports.getHtmlWebpackPlugin = (0, fp_1.pipe)(mergeOption, listify, (0, lodash_1.partial)(getPlugin, HtmlWebpackPlugin));
118exports.getDefinePlugin = (0, fp_1.pipe)(mergeOption, listify, (0, lodash_1.partial)(getPlugin, webpack.DefinePlugin));
119exports.getHotModuleReplacementPlugin = (0, lodash_1.partial)(getPlugin, webpack.HotModuleReplacementPlugin, []);
120const getTerserPlugin = ([enableSourceMap, terserOptions]) => {
121 return new TerserPlugin({
122 cache: true,
123 parallel: true,
124 sourceMap: enableSourceMap,
125 terserOptions: (0, helper_1.recursiveMerge)({}, defaultTerserOption, terserOptions)
126 });
127};
128exports.getTerserPlugin = getTerserPlugin;
129const getCssoWebpackPlugin = ([cssoOption]) => {
130 return (0, fp_1.pipe)(mergeOption, listify, (0, lodash_1.partial)(getPlugin, csso_webpack_plugin_1.default))([defaultCSSCompressOption, cssoOption]);
131};
132exports.getCssoWebpackPlugin = getCssoWebpackPlugin;
133const getCopyWebpackPlugin = ({ copy, appPath }) => {
134 const args = [
135 copy.patterns.map((_a) => {
136 var { from, to } = _a, extra = __rest(_a, ["from", "to"]);
137 return Object.assign({ from, to: path.resolve(appPath, to), context: appPath }, extra);
138 }),
139 copy.options
140 ];
141 return (0, lodash_1.partial)(getPlugin, CopyWebpackPlugin)(args);
142};
143exports.getCopyWebpackPlugin = getCopyWebpackPlugin;
144const getMainPlugin = args => {
145 return (0, lodash_1.partial)(getPlugin, H5Plugin_1.default)([args]);
146};
147exports.getMainPlugin = getMainPlugin;
148const styleModuleReg = /(.*\.module).*\.(css|s[ac]ss|less|styl)\b/;
149const styleGlobalReg = /(.*\.global).*\.(css|s[ac]ss|less|styl)\b/;
150const isNodeModule = (filename) => /\bnode_modules\b/.test(filename);
151const taroModuleRegs = [/@tarojs[/\\_]components/, /\btaro-components\b/];
152const isTaroModule = (filename) => taroModuleRegs.some(reg => reg.test(filename));
153const defaultEsnextModuleRegs = [
154 /@tarojs[/\\_]components/,
155 /\btaro-components\b/,
156 /@tarojs[/\\_]taro-h5/,
157 /\btaro-h5\b/,
158 /@tarojs[/\\_]router/,
159 /\btaro-router\b/,
160 /@tarojs[/\\_]redux-h5/,
161 /\btaro-redux-h5\b/,
162 /@tarojs[/\\_]mobx-h5/,
163 /\btaro-mobx-h5\b/
164];
165const getEsnextModuleRules = esnextModules => {
166 return [...defaultEsnextModuleRegs, ...esnextModules];
167};
168const parseModule = (appPath, { designWidth, deviceRatio, enableExtract, enableSourceMap, styleLoaderOption, cssLoaderOption, lessLoaderOption, sassLoaderOption, stylusLoaderOption, fontUrlLoaderOption, imageUrlLoaderOption, mediaUrlLoaderOption, esnextModules = [], compile, postcss, sourceDir, staticDirectory }) => {
169 const customPostcssOption = postcss || {};
170 const defaultStyleLoaderOption = {
171 /**
172 * 移除singleton设置,会导致样式库优先级发生错误
173 * singleton: true
174 */
175 };
176 const cssModuleOptions = (0, helper_1.recursiveMerge)({}, defaultCssModuleOption, customPostcssOption.cssModules);
177 const { namingPattern, generateScopedName } = cssModuleOptions.config;
178 const cssOptions = [
179 {
180 importLoaders: 1,
181 sourceMap: enableSourceMap,
182 modules: false
183 },
184 cssLoaderOption
185 ];
186 const cssOptionsWithModule = [
187 Object.assign({
188 importLoaders: 1,
189 sourceMap: enableSourceMap,
190 modules: {
191 mode: namingPattern === 'module' ? 'local' : 'global'
192 }
193 }, {
194 modules: typeof generateScopedName === 'function'
195 ? { getLocalIdent: (context, _, localName) => generateScopedName(localName, context.resourcePath) }
196 : { localIdentName: generateScopedName }
197 }),
198 cssLoaderOption
199 ];
200 const esnextModuleRules = getEsnextModuleRules(esnextModules);
201 /**
202 * isEsnextModule
203 *
204 * 使用正则匹配判断是否是es模块
205 * 规则参考:https://github.com/webpack/webpack/blob/master/lib/RuleSet.js#L413
206 */
207 const isEsnextModule = (filename) => esnextModuleRules.some(pattern => {
208 if (pattern instanceof RegExp) {
209 return pattern.test(filename);
210 }
211 else {
212 return filename.indexOf(pattern) > -1;
213 }
214 });
215 const styleLoader = getStyleLoader([defaultStyleLoaderOption, styleLoaderOption]);
216 const topStyleLoader = getStyleLoader([defaultStyleLoaderOption, {
217 insert: function insertAtTop(element) {
218 // eslint-disable-next-line no-var
219 var parent = document.querySelector('head');
220 if (parent) {
221 // eslint-disable-next-line no-var
222 var lastInsertedElement = window._lastElementInsertedByStyleLoader;
223 if (!lastInsertedElement) {
224 parent.insertBefore(element, parent.firstChild);
225 }
226 else if (lastInsertedElement.nextSibling) {
227 parent.insertBefore(element, lastInsertedElement.nextSibling);
228 }
229 else {
230 parent.appendChild(element);
231 }
232 window._lastElementInsertedByStyleLoader = element;
233 }
234 }
235 }, styleLoaderOption]);
236 const extractCssLoader = getExtractCssLoader();
237 const lastStyleLoader = enableExtract ? extractCssLoader : styleLoader;
238 /**
239 * css-loader 1.0.0版本移除了minimize选项...升级需谨慎
240 *
241 * https://github.com/webpack-contrib/css-loader/releases/tag/v1.0.0
242 */
243 const cssLoader = getCssLoader(cssOptions);
244 const cssLoaders = [
245 {
246 use: [cssLoader]
247 }
248 ];
249 if (cssModuleOptions.enable) {
250 const cssLoaderWithModule = getCssLoader(cssOptionsWithModule);
251 let cssModuleCondition;
252 if (cssModuleOptions.config.namingPattern === 'module') {
253 /* 不排除 node_modules 内的样式 */
254 cssModuleCondition = styleModuleReg;
255 // for vue
256 cssLoaders.unshift({
257 resourceQuery: /module=/,
258 use: [cssLoaderWithModule]
259 });
260 }
261 else {
262 cssModuleCondition = {
263 and: [{ exclude: styleGlobalReg }, { exclude: [isNodeModule] }]
264 };
265 }
266 cssLoaders.unshift({
267 include: [cssModuleCondition],
268 use: [cssLoaderWithModule]
269 });
270 }
271 const postcssOption = (0, postcss_conf_1.getDefaultPostcssConfig)({
272 designWidth,
273 deviceRatio,
274 option: customPostcssOption
275 });
276 const postcssLoader = getPostcssLoader([
277 { sourceMap: enableSourceMap },
278 {
279 postcssOptions: {
280 plugins: (0, postcss_conf_1.getPostcssPlugins)(appPath, postcssOption)
281 }
282 }
283 ]);
284 const resolveUrlLoader = getResolveUrlLoader([{}]);
285 const baseSassOptions = {
286 sourceMap: true,
287 implementation: sass,
288 sassOptions: {
289 outputStyle: 'expanded',
290 fiber: false,
291 importer(url, prev, done) {
292 // 让 sass 文件里的 @import 能解析小程序原生样式文体,如 @import "a.wxss";
293 const extname = path.extname(url);
294 // fix: @import 文件可以不带scss/sass缀,如: @import "define";
295 if (extname === '.scss' || extname === '.sass' || extname === '.css' || !extname) {
296 return null;
297 }
298 else {
299 const filePath = path.resolve(path.dirname(prev), url);
300 helper_1.fs.access(filePath, helper_1.fs.constants.F_OK, (err) => {
301 if (err) {
302 console.log(err);
303 return null;
304 }
305 else {
306 helper_1.fs.readFile(filePath)
307 .then(res => {
308 done({ contents: res.toString() });
309 })
310 .catch(err => {
311 console.log(err);
312 return null;
313 });
314 }
315 });
316 }
317 }
318 }
319 };
320 const sassLoader = getSassLoader([baseSassOptions, {
321 sassOptions: {
322 indentedSyntax: true
323 }
324 }, sassLoaderOption]);
325 const scssLoader = getSassLoader([baseSassOptions, sassLoaderOption]);
326 const lessLoader = getLessLoader([{ sourceMap: enableSourceMap }, lessLoaderOption]);
327 const stylusLoader = getStylusLoader([{ sourceMap: enableSourceMap }, stylusLoaderOption]);
328 const scriptRule = {
329 test: helper_1.REG_SCRIPTS,
330 use: {
331 babelLoader: getBabelLoader([{
332 compact: false
333 }]),
334 /** stencil 2.14 开始使用了 import.meta.url 需要额外处理
335 * https://github.com/webpack/webpack/issues/6719
336 */
337 importMeta: getImportMetaLoader([]),
338 }
339 };
340 if (compile.exclude && compile.exclude.length) {
341 scriptRule.exclude = [
342 ...compile.exclude,
343 filename => /css-loader/.test(filename) || (/node_modules/.test(filename) && !(/taro/.test(filename)))
344 ];
345 }
346 else if (compile.include && compile.include.length) {
347 scriptRule.include = [
348 ...compile.include,
349 sourceDir,
350 filename => /taro/.test(filename)
351 ];
352 }
353 else {
354 /**
355 * 要优先处理 css-loader 问题
356 *
357 * https://github.com/webpack-contrib/mini-css-extract-plugin/issues/471#issuecomment-750266195
358 *
359 * 若包含 @tarojs/components,则跳过 babel-loader 处理
360 * 除了包含 taro 和 inversify 的第三方依赖均不经过 babel-loader 处理
361 */
362 scriptRule.exclude = [filename => /css-loader/.test(filename)
363 // || /@tarojs[\\/]components/.test(filename) Note: stencil 2.14 开始使用了 import.meta.url 需要额外处理
364 || (/node_modules/.test(filename) && !(/taro/.test(filename) || /inversify/.test(filename)))];
365 }
366 const rule = {};
367 rule.taroStyle = {
368 test: helper_1.REG_STYLE,
369 use: [topStyleLoader],
370 include: [(filename) => isTaroModule(filename)]
371 };
372 rule.customStyle = {
373 test: helper_1.REG_STYLE,
374 use: [lastStyleLoader],
375 exclude: [(filename) => isTaroModule(filename)]
376 };
377 rule.css = {
378 test: helper_1.REG_STYLE,
379 oneOf: cssLoaders
380 };
381 rule.postcss = {
382 test: helper_1.REG_STYLE,
383 use: [postcssLoader],
384 exclude: [
385 filename => {
386 if (isTaroModule(filename)) {
387 return true;
388 }
389 else if (isEsnextModule(filename)) {
390 return false;
391 }
392 else {
393 return isNodeModule(filename);
394 }
395 }
396 ]
397 };
398 rule.sass = {
399 test: helper_1.REG_SASS_SASS,
400 use: [resolveUrlLoader, sassLoader]
401 };
402 rule.scss = {
403 test: helper_1.REG_SASS_SCSS,
404 use: [resolveUrlLoader, scssLoader]
405 };
406 rule.less = {
407 test: helper_1.REG_LESS,
408 use: [lessLoader]
409 };
410 rule.stylus = {
411 test: helper_1.REG_STYLUS,
412 use: [stylusLoader]
413 };
414 rule.script = scriptRule;
415 rule.media = {
416 test: helper_1.REG_MEDIA,
417 use: {
418 urlLoader: getUrlLoader([
419 defaultMediaUrlLoaderOption,
420 Object.assign({ name: `${staticDirectory}/media/[name].[ext]` }, mediaUrlLoaderOption)
421 ])
422 }
423 };
424 rule.font = {
425 test: helper_1.REG_FONT,
426 use: {
427 urlLoader: getUrlLoader([
428 defaultFontUrlLoaderOption,
429 Object.assign({ name: `${staticDirectory}/fonts/[name].[ext]` }, fontUrlLoaderOption)
430 ])
431 }
432 };
433 rule.image = {
434 test: helper_1.REG_IMAGE,
435 use: {
436 urlLoader: getUrlLoader([
437 defaultImageUrlLoaderOption,
438 Object.assign({ name: `${staticDirectory}/images/[name].[ext]` }, imageUrlLoaderOption)
439 ])
440 }
441 };
442 return { rule, postcssOption };
443};
444exports.parseModule = parseModule;
445const getOutput = (appPath, [{ outputRoot, publicPath, chunkDirectory }, customOutput]) => {
446 return Object.assign({ path: path.resolve(appPath, outputRoot), filename: 'js/[name].js', chunkFilename: `${chunkDirectory}/[name].js`, publicPath }, customOutput);
447};
448exports.getOutput = getOutput;
449const getDevtool = ({ enableSourceMap, sourceMapType = 'cheap-module-eval-source-map' }) => {
450 return enableSourceMap ? sourceMapType : 'none';
451};
452exports.getDevtool = getDevtool;
453//# sourceMappingURL=chain.js.map
\No newline at end of file