UNPKG

@tarojs/mini-runner

Version:

Mini app runner for taro

439 lines 19.2 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.getRuntimeConstants = exports.getDevtool = exports.getOutput = exports.getEntry = exports.getModule = exports.getProviderPlugin = exports.getBuildNativePlugin = exports.getMiniSplitChunksPlugin = exports.getMiniPlugin = exports.getCopyWebpackPlugin = exports.getCssoWebpackPlugin = exports.getTerserPlugin = exports.getDefinePlugin = exports.getMiniCssExtractPlugin = exports.getResolveUrlLoader = exports.getMiniTemplateLoader = exports.getFileLoader = exports.getUrlLoader = exports.getStylusLoader = exports.getLessLoader = exports.getSassLoader = exports.getPostcssLoader = exports.getCssLoader = exports.processEnvOption = exports.mergeOption = exports.makeConfig = void 0; const helper_1 = require("@tarojs/helper"); const runner_utils_1 = require("@tarojs/runner-utils"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const csso_webpack_plugin_1 = require("csso-webpack-plugin"); const lodash_1 = require("lodash"); const fp_1 = require("lodash/fp"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const path = require("path"); const sass = require("sass"); const TerserPlugin = require("terser-webpack-plugin"); const webpack = require("webpack"); const terserOptions_1 = require("../config/terserOptions"); const BuildNativePlugin_1 = require("../plugins/BuildNativePlugin"); const MiniPlugin_1 = require("../plugins/MiniPlugin"); const MiniSplitChunksPlugin_1 = require("../plugins/MiniSplitChunksPlugin"); const postcss_conf_1 = require("./postcss.conf"); const makeConfig = (buildConfig) => __awaiter(void 0, void 0, void 0, function* () { const sassLoaderOption = yield (0, runner_utils_1.getSassLoaderOption)(buildConfig); return Object.assign(Object.assign({}, buildConfig), { sassLoaderOption, frameworkExts: buildConfig.frameworkExts || helper_1.SCRIPT_EXT }); }); exports.makeConfig = makeConfig; const defaultCSSCompressOption = { mergeRules: false, mergeIdents: false, reduceIdents: false, discardUnused: false, minifySelectors: false }; const defaultMediaUrlLoaderOption = { limit: 10240, esModule: false }; const defaultFontUrlLoaderOption = { limit: 10240, esModule: false }; const defaultImageUrlLoaderOption = { limit: 2046, esModule: false }; const defaultCssModuleOption = { enable: false, config: { namingPattern: 'global', generateScopedName: '[name]__[local]___[hash:base64:5]' } }; const defaultUrlOption = { enable: true, config: { limit: 10240 // limit 10k base on document } }; const getLoader = (loaderName, options) => { return { loader: require.resolve(loaderName), options: options || {} }; }; const listify = listOrItem => { if (Array.isArray(listOrItem)) { return listOrItem; } return [listOrItem]; }; const getPlugin = (plugin, args) => { return { plugin, args }; }; const mergeOption = ([...options]) => { return (0, helper_1.recursiveMerge)({}, ...options); }; exports.mergeOption = mergeOption; const styleModuleReg = /(.*\.module).*\.(css|s[ac]ss|less|styl)\b/; const styleGlobalReg = /(.*\.global).*\.(css|s[ac]ss|less|styl)\b/; exports.processEnvOption = (0, lodash_1.partial)(fp_1.mapKeys, (key) => `process.env.${key}`); exports.getCssLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'css-loader')); exports.getPostcssLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'postcss-loader')); exports.getSassLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'sass-loader')); exports.getLessLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'less-loader')); exports.getStylusLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'stylus-loader')); exports.getUrlLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'url-loader')); exports.getFileLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'file-loader')); exports.getMiniTemplateLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, path.resolve(__dirname, '../loaders/miniTemplateLoader'))); exports.getResolveUrlLoader = (0, fp_1.pipe)(exports.mergeOption, (0, lodash_1.partial)(getLoader, 'resolve-url-loader')); const getExtractCssLoader = () => { return { loader: MiniCssExtractPlugin.loader }; }; exports.getMiniCssExtractPlugin = (0, fp_1.pipe)(exports.mergeOption, listify, (0, lodash_1.partial)(getPlugin, MiniCssExtractPlugin)); exports.getDefinePlugin = (0, fp_1.pipe)(exports.mergeOption, listify, (0, lodash_1.partial)(getPlugin, webpack.DefinePlugin)); const getTerserPlugin = ([enableSourceMap, terserOptions]) => { return new TerserPlugin({ cache: true, parallel: true, sourceMap: enableSourceMap, terserOptions: (0, helper_1.recursiveMerge)({}, terserOptions_1.default, terserOptions) }); }; exports.getTerserPlugin = getTerserPlugin; const getCssoWebpackPlugin = ([cssoOption]) => { return (0, fp_1.pipe)(listify, (0, lodash_1.partial)(getPlugin, csso_webpack_plugin_1.default))([(0, exports.mergeOption)([defaultCSSCompressOption, cssoOption]), helper_1.REG_STYLE]); }; exports.getCssoWebpackPlugin = getCssoWebpackPlugin; const getCopyWebpackPlugin = ({ copy, appPath }) => { const args = [ copy.patterns.map((_a) => { var { from, to } = _a, extra = __rest(_a, ["from", "to"]); return Object.assign({ from, to: path.resolve(appPath, to), context: appPath }, extra); }), copy.options ]; return (0, lodash_1.partial)(getPlugin, CopyWebpackPlugin)(args); }; exports.getCopyWebpackPlugin = getCopyWebpackPlugin; const getMiniPlugin = args => { return (0, lodash_1.partial)(getPlugin, MiniPlugin_1.default)([args]); }; exports.getMiniPlugin = getMiniPlugin; const getMiniSplitChunksPlugin = (args) => { return (0, lodash_1.partial)(getPlugin, MiniSplitChunksPlugin_1.default)([args]); }; exports.getMiniSplitChunksPlugin = getMiniSplitChunksPlugin; const getBuildNativePlugin = args => { return (0, lodash_1.partial)(getPlugin, BuildNativePlugin_1.default)([args]); }; exports.getBuildNativePlugin = getBuildNativePlugin; const getProviderPlugin = args => { return (0, lodash_1.partial)(getPlugin, webpack.ProvidePlugin)([args]); }; exports.getProviderPlugin = getProviderPlugin; const getModule = (appPath, { sourceDir, designWidth, deviceRatio, buildAdapter, isBuildQuickapp, // constantsReplaceList, enableSourceMap, compile, cssLoaderOption, lessLoaderOption, sassLoaderOption, stylusLoaderOption, fontUrlLoaderOption, imageUrlLoaderOption, mediaUrlLoaderOption, postcss, fileType }) => { const postcssOption = postcss || {}; const cssModuleOptions = (0, helper_1.recursiveMerge)({}, defaultCssModuleOption, postcssOption.cssModules); const { namingPattern, generateScopedName } = cssModuleOptions.config; const cssOptions = [ { importLoaders: 1, sourceMap: enableSourceMap, modules: false }, cssLoaderOption ]; const cssOptionsWithModule = [ Object.assign({ importLoaders: 1, sourceMap: enableSourceMap, modules: { mode: namingPattern === 'module' ? 'local' : 'global' } }, { modules: typeof generateScopedName === 'function' ? { getLocalIdent: (context, _, localName) => generateScopedName(localName, context.resourcePath) } : { localIdentName: generateScopedName } }), cssLoaderOption ]; const extractCssLoader = getExtractCssLoader(); const miniTemplateLoader = (0, exports.getMiniTemplateLoader)([{ buildAdapter }]); const cssLoader = (0, exports.getCssLoader)(cssOptions); const baseSassOptions = { sourceMap: true, implementation: sass, sassOptions: { outputStyle: 'expanded', fiber: false, importer(url, prev, done) { // 让 sass 文件里的 @import 能解析小程序原生样式文体,如 @import "a.wxss"; const extname = path.extname(url); // fix: @import 文件可以不带scss/sass缀,如: @import "define"; if (extname === '.scss' || extname === '.sass' || extname === '.css' || !extname) { return null; } else { const filePath = path.resolve(path.dirname(prev), url); helper_1.fs.access(filePath, helper_1.fs.constants.F_OK, (err) => { if (err) { console.log(err); return null; } else { helper_1.fs.readFile(filePath) .then(res => { done({ contents: res.toString() }); }) .catch(err => { console.log(err); return null; }); } }); } } } }; const sassLoader = (0, exports.getSassLoader)([baseSassOptions, { sassOptions: { indentedSyntax: true } }, sassLoaderOption]); const scssLoader = (0, exports.getSassLoader)([baseSassOptions, sassLoaderOption]); const resolveUrlLoader = (0, exports.getResolveUrlLoader)([{}]); const postcssLoader = (0, exports.getPostcssLoader)([ { sourceMap: enableSourceMap }, { postcssOptions: { plugins: (0, postcss_conf_1.getPostcssPlugins)(appPath, { isBuildQuickapp, designWidth, deviceRatio, postcssOption }) } } ]); const lessLoader = (0, exports.getLessLoader)([{ sourceMap: enableSourceMap }, lessLoaderOption]); const stylusLoader = (0, exports.getStylusLoader)([{ sourceMap: enableSourceMap }, stylusLoaderOption]); const cssLoaders = [{ use: [ extractCssLoader, cssLoader, postcssLoader ] }]; if (cssModuleOptions.enable) { const cssLoaderWithModule = (0, exports.getCssLoader)(cssOptionsWithModule); let cssModuleCondition; if (cssModuleOptions.config.namingPattern === 'module') { /* 不排除 node_modules 内的样式 */ cssModuleCondition = styleModuleReg; // for vue cssLoaders.unshift({ resourceQuery: /module=/, use: [ extractCssLoader, cssLoaderWithModule, postcssLoader ] }); } else { cssModuleCondition = { and: [ { exclude: styleGlobalReg }, { exclude: [helper_1.isNodeModule] } ] }; } cssLoaders.unshift({ include: [cssModuleCondition], use: [ extractCssLoader, cssLoaderWithModule, postcssLoader ] }); } const urlOptions = (0, helper_1.recursiveMerge)({}, defaultUrlOption, postcssOption.url); let postcssUrlOption; if (urlOptions.enable) { postcssUrlOption = urlOptions.config; } function addCssLoader(cssLoaders, ...loader) { const cssLoadersCopy = (0, lodash_1.cloneDeep)(cssLoaders); cssLoadersCopy.forEach(item => { if (item.use) { item.use = [...item.use, ...loader]; } }); return cssLoadersCopy; } const scriptRule = { test: helper_1.REG_SCRIPTS, use: { babelLoader: { loader: require.resolve('babel-loader') } } }; if (compile.exclude && compile.exclude.length) { scriptRule.exclude = [ ...compile.exclude, filename => /css-loader/.test(filename) || (/node_modules/.test(filename) && !(/taro/.test(filename))) ]; } else if (compile.include && compile.include.length) { scriptRule.include = [ ...compile.include, sourceDir, filename => /taro/.test(filename) ]; } else { scriptRule.exclude = [filename => /css-loader/.test(filename) || (/node_modules/.test(filename) && !(/taro/.test(filename)))]; } const rule = { sass: { test: helper_1.REG_SASS_SASS, oneOf: addCssLoader(cssLoaders, resolveUrlLoader, sassLoader) }, scss: { test: helper_1.REG_SASS_SCSS, oneOf: addCssLoader(cssLoaders, resolveUrlLoader, scssLoader) }, less: { test: helper_1.REG_LESS, oneOf: addCssLoader(cssLoaders, lessLoader) }, stylus: { test: helper_1.REG_STYLUS, oneOf: addCssLoader(cssLoaders, stylusLoader) }, nomorlCss: { test: helper_1.REG_CSS, oneOf: cssLoaders }, script: scriptRule, template: { test: helper_1.REG_TEMPLATE, use: [(0, exports.getFileLoader)([{ useRelativePath: true, name: `[path][name]${fileType.templ}`, context: sourceDir }]), miniTemplateLoader] }, media: { test: helper_1.REG_MEDIA, use: { urlLoader: (0, exports.getUrlLoader)([defaultMediaUrlLoaderOption, Object.assign(Object.assign({ name: '[path][name].[ext]', useRelativePath: true, context: sourceDir }, (postcssUrlOption || {})), mediaUrlLoaderOption)]) } }, font: { test: helper_1.REG_FONT, use: { urlLoader: (0, exports.getUrlLoader)([defaultFontUrlLoaderOption, Object.assign(Object.assign({ name: '[path][name].[ext]', useRelativePath: true, context: sourceDir }, (postcssUrlOption || {})), fontUrlLoaderOption)]) } }, image: { test: helper_1.REG_IMAGE, use: { urlLoader: (0, exports.getUrlLoader)([defaultImageUrlLoaderOption, Object.assign(Object.assign({ name: '[path][name].[ext]', useRelativePath: true, context: sourceDir }, (postcssUrlOption || {})), imageUrlLoaderOption)]) } } }; return { rule }; }; exports.getModule = getModule; const getEntry = ({ sourceDir, entry, isBuildPlugin }) => { if (!isBuildPlugin) { return { entry }; } const pluginDir = path.join(sourceDir, 'plugin'); if (!helper_1.fs.existsSync(pluginDir)) { console.log(helper_1.chalk.red('插件目录不存在,请检查!')); return; } const pluginConfigPath = path.join(pluginDir, 'plugin.json'); if (!helper_1.fs.existsSync(pluginConfigPath)) { console.log(helper_1.chalk.red('缺少插件配置文件,请检查!')); return; } const pluginConfig = helper_1.fs.readJSONSync(pluginConfigPath); const entryObj = {}; let pluginMainEntry; Object.keys(pluginConfig).forEach(key => { if (key === 'main') { const filePath = path.join(pluginDir, pluginConfig[key]); const fileName = path.basename(filePath).replace(path.extname(filePath), ''); pluginMainEntry = `plugin/${fileName}`; entryObj[pluginMainEntry] = [(0, helper_1.resolveMainFilePath)(filePath.replace(path.extname(filePath), ''))]; } else if (key === 'publicComponents' || key === 'pages') { Object.keys(pluginConfig[key]).forEach(subKey => { const filePath = path.join(pluginDir, pluginConfig[key][subKey]); entryObj[`plugin/${pluginConfig[key][subKey]}`] = [(0, helper_1.resolveMainFilePath)(filePath.replace(path.extname(filePath), ''))]; }); } }); return { entry: entryObj, pluginConfig, pluginMainEntry }; }; exports.getEntry = getEntry; function getOutput(appPath, [{ outputRoot, publicPath, globalObject }, customOutput]) { return Object.assign({ path: path.resolve(appPath, outputRoot), publicPath, filename: '[name].js', chunkFilename: '[name].js', globalObject }, customOutput); } exports.getOutput = getOutput; function getDevtool(enableSourceMap, sourceMapType = 'cheap-module-source-map') { return enableSourceMap ? sourceMapType : 'none'; } exports.getDevtool = getDevtool; function getRuntimeConstants(runtime) { var _a, _b, _c, _d, _e, _f, _g; const constants = {}; constants.ENABLE_INNER_HTML = (_a = runtime.enableInnerHTML) !== null && _a !== void 0 ? _a : true; constants.ENABLE_ADJACENT_HTML = (_b = runtime.enableAdjacentHTML) !== null && _b !== void 0 ? _b : false; constants.ENABLE_SIZE_APIS = (_c = runtime.enableSizeAPIs) !== null && _c !== void 0 ? _c : false; constants.ENABLE_TEMPLATE_CONTENT = (_d = runtime.enableTemplateContent) !== null && _d !== void 0 ? _d : false; constants.ENABLE_CLONE_NODE = (_e = runtime.enableCloneNode) !== null && _e !== void 0 ? _e : false; constants.ENABLE_CONTAINS = (_f = runtime.enableContains) !== null && _f !== void 0 ? _f : false; constants.ENABLE_MUTATION_OBSERVER = (_g = runtime.enableMutationObserver) !== null && _g !== void 0 ? _g : false; return constants; } exports.getRuntimeConstants = getRuntimeConstants; //# sourceMappingURL=chain.js.map