├── .fatherrc.ts ├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── README.md ├── demo ├── .editorconfig ├── .env ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .umirc.ts ├── README.md ├── mock │ └── .gitkeep ├── package.json ├── pnpm-lock.yaml ├── src │ └── pages │ │ ├── index.less │ │ └── index.tsx ├── tsconfig.json ├── typings.d.ts └── wdist │ └── index.html ├── package.json ├── pnpm-lock.yaml ├── src ├── bundler-mako.ts ├── index.ts └── utils.ts └── tsconfig.json /.fatherrc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'father'; 2 | 3 | export default defineConfig({ 4 | cjs: { 5 | output: 'dist', 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /packages/*/lib 3 | /packages/*/dist 4 | /packages/*/node_modules 5 | /packages/deps/bundles/node_modules 6 | /coverage 7 | /.nyc_output 8 | /.changelog 9 | /dist 10 | .DS_Store 11 | .umi 12 | .umi-production 13 | .umi-test 14 | **/fixtures/**/dist 15 | .now 16 | **/*.less.d.ts 17 | **/*.css.d.ts 18 | report.*.json 19 | output.txt 20 | /examples/*/dist 21 | /packages/bundler-webpack/src/fixtures/outputPath/bar 22 | /examples/**/node_modules 23 | /examples/*/yarn.lock 24 | /examples/*/app/public 25 | /examples/*/logs 26 | /examples/*/run 27 | /examples/*/.idea 28 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .umi 3 | .umi-production 4 | *.png 5 | *.jpg 6 | *.svg 7 | *.less 8 | .editorconfig 9 | .env 10 | .prettierignore 11 | .gitkeep 12 | .DS_Store 13 | .npmrc 14 | .eslintignore 15 | .gitignore 16 | dist 17 | lib 18 | es 19 | pnpm-lock.yaml 20 | cache.json 21 | coverage 22 | *.test.ts.snap -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 80, 3 | singleQuote: true, 4 | trailingComma: 'all', 5 | proseWrap: 'never', 6 | endOfLine: 'lf', 7 | overrides: [{ files: '.prettierrc', options: { parser: 'json' } }], 8 | plugins: [ 9 | require.resolve('prettier-plugin-packagejson'), 10 | require.resolve('prettier-plugin-organize-imports'), 11 | ], 12 | pluginSearchDirs: false, 13 | }; 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mako Plugin for Umi@3 2 | 3 | ## Install 4 | 5 | ```bash 6 | $ npm i umi-plugin-mako -D 7 | ``` 8 | 9 | ## Usage 10 | 11 | Enable by config. 12 | 13 | ```ts 14 | import { defineConfig } from 'umi'; 15 | 16 | export default defineConfig({ 17 | mako: { 18 | // mako.config.json 19 | // mako config 20 | }, 21 | }); 22 | ``` 23 | 24 | ### Build 25 | 26 | ```bash 27 | $ umi build 28 | 29 | INFO Using mako@0.7.4 30 | Building with mako for production... 31 | dist/umi.css 0.04 kB 32 | dist/umi.js 403.76 kB 33 | ✓ Built in 571ms 34 | Complete! 35 | File Size Gzipped 36 | 37 | dist/umi.js 394.3 KB 93.3 KB 38 | dist/umi.css 35.0 B 55.0 B 39 | 40 | Images and other types of assets omitted. 41 | 42 | mako build complete 43 | ``` 44 | 45 | ### Dev 46 | 47 | ```bash 48 | $ umi dev 49 | 50 | INFO Using mako@0.7.4 51 | Starting the development server... 52 | http://localhost:8000 53 | Building with mako for development... 54 | ✓ Built in 352ms 55 | ``` 56 | 57 | ## LICENSE 58 | 59 | MIT 60 | 61 | ## Example 62 | 63 | Please refer to [umi-antd-pro](https://github.com/alitajs/umi-antd-pro)'s [commit](https://github.com/alitajs/umi-antd-pro/commit/03103c82a78acbb1e27db46a26cbff2d77ff3d09) for usage cases 64 | 65 | webpack 66 | 67 | ```bash 68 | Theme generated successfully 69 | DONE Compiled successfully in 38919ms 15:00:51 70 | 71 | ✨ Done in 41.77s. 72 | ``` 73 | 74 | mako 75 | 76 | ```bash 77 | 78 | ✓ Built in 4807ms 79 | mako build complete 80 | ✨ Done in 7.82s. 81 | ``` 82 | -------------------------------------------------------------------------------- /demo/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /demo/.env: -------------------------------------------------------------------------------- 1 | ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION=site 2 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /demo/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /demo/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /demo/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env; 3 | 4 | export default defineConfig({ 5 | nodeModulesTransform: { 6 | type: 'none', 7 | }, 8 | theme: { 9 | 'primary-color': '#00FF00', 10 | }, 11 | routes: [{ path: '/', component: '@/pages/index' }], 12 | fastRefresh: {}, 13 | mfsu: false, 14 | plugins: ['../dist/index'], 15 | mako: { 16 | px2rem: {}, 17 | }, 18 | define: { 19 | ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 20 | ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION || '', // preview.pro.ant.design only do not use in your production ; preview.pro.ant.design 专用环境变量,请不要在你的项目中使用它。 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # umi project 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /demo/mock/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umijs/umi-plugin-mako/d97f5a41423809696c223941cf8ec2230a1a44ce/demo/mock/.gitkeep -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "umi dev", 5 | "start": "umi dev", 6 | "build": "umi build", 7 | "postinstall": "umi generate tmp", 8 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 9 | "test": "umi-test", 10 | "test:coverage": "umi-test --coverage" 11 | }, 12 | "gitHooks": { 13 | "pre-commit": "lint-staged" 14 | }, 15 | "lint-staged": { 16 | "*.{js,jsx,less,md,json}": [ 17 | "prettier --write" 18 | ], 19 | "*.ts?(x)": [ 20 | "prettier --parser=typescript --write" 21 | ] 22 | }, 23 | "dependencies": { 24 | "@ant-design/pro-layout": "^6.5.0", 25 | "react": "17.x", 26 | "react-dom": "17.x", 27 | "umi": "^3.5.41" 28 | }, 29 | "devDependencies": { 30 | "@types/react": "^17.0.0", 31 | "@types/react-dom": "^17.0.0", 32 | "@umijs/preset-react": "1.x", 33 | "@umijs/test": "^3.5.41", 34 | "lint-staged": "^10.0.7", 35 | "prettier": "^2.2.0", 36 | "typescript": "^4.1.2", 37 | "yorkie": "^2.0.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demo/src/pages/index.less: -------------------------------------------------------------------------------- 1 | .title { 2 | background: @primary-color; 3 | font-size: 515px; 4 | } 5 | -------------------------------------------------------------------------------- /demo/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import styles from './index.less'; 2 | 3 | export default function IndexPage() { 4 | // @ts-ignore 5 | console.log(ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION); 6 | return ( 7 |
8 |

Page index

9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "resolveJsonModule": true, 7 | "importHelpers": true, 8 | "jsx": "react-jsx", 9 | "esModuleInterop": true, 10 | "sourceMap": true, 11 | "baseUrl": "./", 12 | "strict": true, 13 | "paths": { 14 | "@/*": ["src/*"], 15 | "@@/*": ["src/.umi/*"] 16 | }, 17 | "allowSyntheticDefaultImports": true 18 | }, 19 | "include": [ 20 | "mock/**/*", 21 | "src/**/*", 22 | "config/**/*", 23 | ".umirc.ts", 24 | "typings.d.ts" 25 | ], 26 | "exclude": [ 27 | "node_modules", 28 | "lib", 29 | "es", 30 | "dist", 31 | "typings", 32 | "**/__test__", 33 | "test", 34 | "docs", 35 | "tests" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /demo/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module '*.png'; 4 | declare module '*.svg' { 5 | export function ReactComponent( 6 | props: React.SVGProps, 7 | ): React.ReactElement; 8 | const url: string; 9 | export default url; 10 | } 11 | -------------------------------------------------------------------------------- /demo/wdist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 13 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "umi-plugin-mako", 3 | "version": "0.0.13", 4 | "description": "", 5 | "keywords": [ 6 | "mako", 7 | "umi@3", 8 | "umijs" 9 | ], 10 | "homepage": "https://github.com/umijs/umi-plugin-mako", 11 | "license": "MIT", 12 | "author": "xiaohuoni", 13 | "main": "dist/index.js", 14 | "types": "dist/index.d.ts", 15 | "files": [ 16 | "dist" 17 | ], 18 | "scripts": { 19 | "build": "father build", 20 | "format": "prettier --write .", 21 | "start": "father dev" 22 | }, 23 | "dependencies": { 24 | "@umijs/bundler-webpack": "3.5.41", 25 | "@umijs/deps": "3.5.41", 26 | "@umijs/mako": "0.9.5", 27 | "@umijs/preset-built-in": "3.5.41", 28 | "@umijs/types": "3.x", 29 | "compression": "^1.7.4", 30 | "connect-history-api-fallback": "^2.0.0", 31 | "core-js": "^3.37.1", 32 | "cors": "^2.8.5", 33 | "get-tsconfig": "4.7.5", 34 | "http-proxy-middleware": "2.0.6", 35 | "lodash": "^4.17.21" 36 | }, 37 | "devDependencies": { 38 | "@types/lodash": "^4.17.6", 39 | "father": "^4.4.4", 40 | "prettier": "^2.5.1", 41 | "prettier-plugin-organize-imports": "^3.2.4", 42 | "prettier-plugin-packagejson": "^2.5.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/bundler-mako.ts: -------------------------------------------------------------------------------- 1 | import { Bundler as WebpackBundler } from '@umijs/bundler-webpack'; 2 | import { createProxyMiddleware } from 'http-proxy-middleware'; 3 | import { getDevBanner, getMakoConfig, getStats } from './utils'; 4 | 5 | class Bundler extends WebpackBundler { 6 | static id = 'mako'; 7 | static version = 1; 8 | 9 | constructor(opts: any) { 10 | super(opts); 11 | } 12 | 13 | async build({ 14 | bundleConfigs, 15 | watch, 16 | onBuildComplete, 17 | }: { 18 | bundleConfigs: any; 19 | watch?: boolean; 20 | onBuildComplete?: any; 21 | }): Promise<{ stats?: any; compiler: any }> { 22 | return new Promise((resolve, reject) => { 23 | const { build } = require('@umijs/mako'); 24 | if (watch) { 25 | // TODO: build 为什么有 watch ? 26 | // dev 好像不走这里 27 | } 28 | const config = bundleConfigs[0]; 29 | const makoConfig = getMakoConfig(this.config, config); 30 | makoConfig.plugins ??= []; 31 | let statsJson: any; 32 | makoConfig.plugins.push({ 33 | name: 'mako-stats', 34 | generateEnd: (args: any) => { 35 | statsJson = args.stats; 36 | }, 37 | }); 38 | build({ 39 | root: this.cwd, 40 | config: makoConfig, 41 | watch: false, 42 | }) 43 | .then(() => { 44 | const statsUtil = getStats(statsJson); 45 | onBuildComplete?.(null, statsUtil); 46 | resolve({ stats: statsUtil, compiler: {} }); 47 | }) 48 | .catch((err: any) => { 49 | reject(err); 50 | }); 51 | }); 52 | } 53 | setupDevServerOpts({ bundleConfigs }: { bundleConfigs: any }): any { 54 | const config = bundleConfigs[0]; 55 | const makoConfig = getMakoConfig(this.config, config); 56 | 57 | return { 58 | onListening: async ({ port, hostname, listeningApp }: any) => { 59 | const hmrPort = port + 1; 60 | // proxy ws to mako server 61 | const wsProxy = createProxyMiddleware({ 62 | // mako server in the same host so hard code is ok 63 | target: `http://${hostname}:${hmrPort}`, 64 | ws: true, 65 | logLevel: 'silent', 66 | }); 67 | listeningApp.on('upgrade', wsProxy.upgrade); 68 | // mako dev 69 | const { build } = require('@umijs/mako'); 70 | makoConfig.hmr = {}; 71 | makoConfig.plugins ??= []; 72 | makoConfig.devServer = { port: port + 1, host: hostname }; 73 | makoConfig.plugins.push({ 74 | name: 'mako-dev', 75 | generateEnd: (args: any) => { 76 | const statsUtil = getStats(args.stats); 77 | const compilation = statsUtil.toJson(); 78 | // console.log(args.stats); 79 | // onDevCompileDone { startTime: 1720582011441, endTime: 1720582011804 } 80 | // console.log('onDevCompileDone', args); 81 | config.onCompileDone?.({ 82 | ...args, 83 | stats: { 84 | ...args?.stats, 85 | compilation, 86 | }, 87 | }); 88 | if (args.isFirstCompile) { 89 | const protocol = this.config.https ? 'https:' : 'http:'; 90 | const banner = getDevBanner(protocol, hostname, port); 91 | console.log(banner); 92 | } 93 | }, 94 | }); 95 | try { 96 | await build({ 97 | root: this.cwd, 98 | config: makoConfig, 99 | watch: true, 100 | }); 101 | } catch (e: any) { 102 | // opts.onBuildError?.(e); 103 | config.onCompileFail?.(e); 104 | console.error(e.message); 105 | const err: any = new Error('Build with mako failed.'); 106 | err.stack = null; 107 | throw err; 108 | } 109 | }, 110 | onConnection: ({ connection, server }: any) => {}, 111 | }; 112 | } 113 | } 114 | 115 | export { Bundler }; 116 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { IApi } from '@umijs/types'; 2 | import path from 'path'; 3 | import { Bundler } from './bundler-mako'; 4 | // @ts-ignore 5 | import express from '@umijs/deps/compiled/express'; 6 | // @ts-ignore 7 | import { getHtmlGenerator } from '@umijs/preset-built-in/lib/plugins/commands/htmlUtils'; 8 | import { writeFileSync } from 'fs'; 9 | import { join } from 'path'; 10 | 11 | export default function (api: IApi) { 12 | api.describe({ 13 | key: 'mako', 14 | config: { 15 | schema(joi) { 16 | return joi.object(); 17 | }, 18 | }, 19 | }); 20 | if (!api.userConfig.mako) return; 21 | if (api.userConfig.ssr) { 22 | console.log('mako bundler no support ssr!'); 23 | return; 24 | } 25 | api.modifyConfig(async (memo) => { 26 | return { 27 | ...memo, 28 | mfsu: false, 29 | }; 30 | }); 31 | api.modifyBundler(() => { 32 | return Bundler; 33 | }); 34 | api.onStart(() => { 35 | process.env.HMR = 'none'; 36 | try { 37 | const pkg = require(path.join( 38 | require.resolve('@umijs/mako'), 39 | '../../package.json', 40 | )); 41 | api.logger.info(`Using mako@${pkg.version}`); 42 | } catch (e) { 43 | console.error(e); 44 | } 45 | }); 46 | 47 | api.onBuildComplete(async ({ err, stats }) => { 48 | console.log('mako build complete'); 49 | if (!err) { 50 | const compilation = (stats as any).toJson(); 51 | const html = getHtmlGenerator({ api }); 52 | const routeMap = await api.applyPlugins({ 53 | key: 'modifyExportRouteMap', 54 | type: api.ApplyPluginsType.modify, 55 | initialValue: [{ route: { path: '/' }, file: 'index.html' }], 56 | args: { 57 | html, 58 | }, 59 | }); 60 | for (const { route, file } of routeMap) { 61 | const defaultContent = await html.getContent({ 62 | route, 63 | assets: compilation.assets, 64 | chunks: compilation.chunks, 65 | }); 66 | const content = await api.applyPlugins({ 67 | key: 'modifyProdHTMLContent', 68 | type: api.ApplyPluginsType.modify, 69 | initialValue: defaultContent, 70 | args: { 71 | route, 72 | file, 73 | }, 74 | }); 75 | const outputHtml = join(api.paths.absOutputPath!, file); 76 | writeFileSync(outputHtml, content, 'utf-8'); 77 | } 78 | } 79 | }); 80 | api.addBeforeMiddlewares(() => { 81 | const outputPath = path.resolve( 82 | api.paths.cwd!, 83 | api.config.outputPath || 'dist', 84 | ); 85 | // cors 86 | // compression 87 | // history fallback 88 | // serve dist files 89 | return [ 90 | require('cors')({ 91 | origin: true, 92 | methods: ['GET', 'HEAD', 'PUT', 'POST', 'PATCH', 'DELETE', 'OPTIONS'], 93 | credentials: true, 94 | }), 95 | require('compression')(), 96 | require('connect-history-api-fallback')({ 97 | index: '/', 98 | }), 99 | express.static(outputPath), 100 | ]; 101 | }); 102 | api.modifyBundleConfig((bundleConfig: any, { bundler: { id }, type }) => { 103 | if (id === 'mako') { 104 | bundleConfig.onCompileDone = ({ isFirstCompile, stats }: any) => { 105 | if (isFirstCompile) { 106 | api.service.emit('firstDevCompileDone'); 107 | } 108 | api 109 | .applyPlugins({ 110 | key: 'onDevCompileDone', 111 | type: api.ApplyPluginsType.event, 112 | args: { 113 | isFirstCompile, 114 | type, 115 | stats, 116 | }, 117 | }) 118 | .catch((e) => { 119 | console.error(e.stack); 120 | }); 121 | }; 122 | bundleConfig.onCompileFail = () => {}; 123 | } 124 | return bundleConfig; 125 | }); 126 | } 127 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import address from '@umijs/deps/compiled/address'; 2 | import chalk from '@umijs/deps/compiled/chalk'; 3 | import lodash from 'lodash'; 4 | import path from 'path'; 5 | 6 | function getLessSourceMapConfig(devtool: any) { 7 | return ( 8 | devtool && { 9 | sourceMapFileInline: true, 10 | outputSourceFiles: true, 11 | } 12 | ); 13 | } 14 | export const getMakoConfig = (config: any, bundleConfig: any) => { 15 | const define: any = {}; 16 | function normalizeDefineValue(val: string) { 17 | if (!lodash.isPlainObject(val)) { 18 | return JSON.stringify(val); 19 | } else { 20 | return Object.keys(val).reduce((obj: any, key: any) => { 21 | obj[key] = normalizeDefineValue(val[key]); 22 | return obj; 23 | }, {}); 24 | } 25 | } 26 | if (config.define) { 27 | for (const key of Object.keys(config.define)) { 28 | // mako 的 define 会先去判断 process.env.xxx,再去判断 xxx 29 | // 这里传 process.env.xxx 反而不会生效 30 | // TODO: 待 mako 改成和 umi/webpack 的方式一致之后,可以把这段去掉 31 | if (key.startsWith('process.env.')) { 32 | define[key.replace(/^process\.env\./, '')] = normalizeDefineValue( 33 | config.define[key], 34 | ); 35 | } else { 36 | define[key] = normalizeDefineValue(config.define[key]); 37 | } 38 | } 39 | } 40 | // mako build need alias array 41 | const generatorAlias = Object.keys(bundleConfig.resolve.alias).map((key) => { 42 | return [key, bundleConfig.resolve.alias[key]]; 43 | }); 44 | // mako build need entry object 45 | const generatorEntry: any = {}; 46 | Object.keys(bundleConfig.entry).forEach((key) => { 47 | generatorEntry[key] = bundleConfig.entry[key][0]; 48 | }); 49 | 50 | const normalizedDevtool = config.devtool === false ? false : 'source-map'; 51 | 52 | return { 53 | mode: bundleConfig.mode, 54 | devtool: config.devtool, 55 | autoCSSModules: true, 56 | less: { 57 | modifyVars: config.lessLoader?.modifyVars || config.theme, 58 | globalVars: config.lessLoader?.globalVars, 59 | sourceMap: getLessSourceMapConfig(normalizedDevtool), 60 | math: config.lessLoader?.math, 61 | plugins: config.lessLoader?.plugins, 62 | }, 63 | resolve: { alias: generatorAlias }, 64 | entry: generatorEntry, 65 | // always enable stats to provide json for onBuildComplete hook 66 | stats: { 67 | modules: false, 68 | }, 69 | define, 70 | sass: config?.sass, 71 | ...(config?.mako || {}), 72 | }; 73 | }; 74 | 75 | export const getStats = (statsJson?: any) => { 76 | // 手动对标 chunks,主要是 @umijs/preset-built-in/lib/plugins/commands/htmlUtils.js 中用于生成 html 77 | const stats = { 78 | compilation: { 79 | ...statsJson, 80 | chunks: statsJson.chunks.map((chunk: any) => { 81 | chunk.name = path.basename(chunk.id, path.extname(chunk.id)); 82 | return chunk; 83 | }), 84 | }, 85 | hasErrors: () => false, 86 | }; 87 | const statsUtil = { 88 | toJson: () => stats.compilation, 89 | }; 90 | return statsUtil; 91 | }; 92 | 93 | export const getDevBanner = (protocol: any, host: string, port: any) => { 94 | const ip = address.ip(); 95 | const hostStr = host === '0.0.0.0' ? 'localhost' : host; 96 | const messages = []; 97 | messages.push(' App listening at:'); 98 | messages.push( 99 | ` - Local: ${chalk.cyan(`${protocol}//${hostStr}:${port}`)}`, 100 | ); 101 | messages.push(` - Network: ${chalk.cyan(`${protocol}//${ip}:${port}`)}`); 102 | return messages.join('\n'); 103 | }; 104 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "moduleResolution": "node", 5 | "jsx": "preserve", 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "experimentalDecorators": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noImplicitReturns": true, 13 | "declaration": true, 14 | "resolveJsonModule": true 15 | }, 16 | "exclude": ["node_modules", "dist", "**/*.spec.ts", "lib", "demo"] 17 | } 18 | --------------------------------------------------------------------------------