修改了webpack的初始化过程,增加了注入
This commit is contained in:
parent
0ad9aa5e4a
commit
49454f9ee0
|
|
@ -81,7 +81,7 @@ const resolveModule = (resolveFn, filePath) => {
|
||||||
return resolveFn(`${filePath}.js`);
|
return resolveFn(`${filePath}.js`);
|
||||||
};
|
};
|
||||||
|
|
||||||
// config after eject: we're in ./config/
|
// config after eject: we're in ./web
|
||||||
module.exports = {
|
module.exports = {
|
||||||
dotenv: resolveApp('.env'),
|
dotenv: resolveApp('.env'),
|
||||||
appPath: resolveApp('.'),
|
appPath: resolveApp('.'),
|
||||||
|
|
|
||||||
|
|
@ -205,15 +205,20 @@ module.exports = function (webpackEnv) {
|
||||||
return loaders;
|
return loaders;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 读取编译配置
|
||||||
|
const compilerConfigurationFile = path.join(paths.appRootPath, 'configuration', 'compiler.js');
|
||||||
|
const projectConfigration = fs.existsSync(compilerConfigurationFile) && require(compilerConfigurationFile).webpack;
|
||||||
|
|
||||||
const getOakInclude = () => {
|
const getOakInclude = () => {
|
||||||
return [
|
const result = [
|
||||||
/oak-domain/,
|
|
||||||
/oak-external-sdk/,
|
|
||||||
/oak-frontend-base/,
|
/oak-frontend-base/,
|
||||||
/oak-general-business/,
|
/oak-general-business/,
|
||||||
/oak-memory-tree-store/,
|
|
||||||
/oak-common-aspect/,
|
|
||||||
];
|
];
|
||||||
|
if (projectConfigration && projectConfigration.extraOakModules) {
|
||||||
|
result.push(...projectConfigration.extraOakModules);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -255,14 +260,14 @@ module.exports = function (webpackEnv) {
|
||||||
// Point sourcemap entries to original disk location (format as URL on Windows)
|
// Point sourcemap entries to original disk location (format as URL on Windows)
|
||||||
devtoolModuleFilenameTemplate: isEnvProduction
|
devtoolModuleFilenameTemplate: isEnvProduction
|
||||||
? (info) =>
|
? (info) =>
|
||||||
path
|
path
|
||||||
.relative(paths.appSrc, info.absoluteResourcePath)
|
.relative(paths.appSrc, info.absoluteResourcePath)
|
||||||
.replace(/\\/g, '/')
|
.replace(/\\/g, '/')
|
||||||
: isEnvDevelopment &&
|
: isEnvDevelopment &&
|
||||||
((info) =>
|
((info) =>
|
||||||
path
|
path
|
||||||
.resolve(info.absoluteResourcePath)
|
.resolve(info.absoluteResourcePath)
|
||||||
.replace(/\\/g, '/')),
|
.replace(/\\/g, '/')),
|
||||||
},
|
},
|
||||||
cache: {
|
cache: {
|
||||||
type: 'filesystem',
|
type: 'filesystem',
|
||||||
|
|
@ -369,18 +374,24 @@ module.exports = function (webpackEnv) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
fallback: {
|
fallback: (() => {
|
||||||
crypto: require.resolve('crypto-browserify'),
|
const defaultFb = {
|
||||||
buffer: require.resolve('safe-buffer'),
|
crypto: require.resolve('crypto-browserify'),
|
||||||
stream: require.resolve('stream-browserify'),
|
buffer: require.resolve('safe-buffer'),
|
||||||
zlib: require.resolve('browserify-zlib'),
|
stream: require.resolve('stream-browserify'),
|
||||||
querystring: require.resolve('querystring-es3'),
|
zlib: require.resolve('browserify-zlib'),
|
||||||
url: false,
|
querystring: require.resolve('querystring-es3'),
|
||||||
path: false,
|
url: false,
|
||||||
fs: false,
|
path: false,
|
||||||
net: false,
|
fs: false,
|
||||||
tls: false,
|
net: false,
|
||||||
},
|
tls: false,
|
||||||
|
}
|
||||||
|
if (projectConfigration && projectConfigration.resolve && projectConfigration.resolve.fallback) {
|
||||||
|
Object.assign(defaultFb, projectConfigration.resolve.fallback);
|
||||||
|
}
|
||||||
|
return defaultFb;
|
||||||
|
})(),
|
||||||
// This allows you to set a fallback for where webpack should look for modules.
|
// This allows you to set a fallback for where webpack should look for modules.
|
||||||
// We placed these paths second because we want `node_modules` to "win"
|
// We placed these paths second because we want `node_modules` to "win"
|
||||||
// if there are any conflicts. This matches Node resolution mechanism.
|
// if there are any conflicts. This matches Node resolution mechanism.
|
||||||
|
|
@ -397,24 +408,25 @@ module.exports = function (webpackEnv) {
|
||||||
extensions: paths.moduleFileExtensions
|
extensions: paths.moduleFileExtensions
|
||||||
.map((ext) => `.${ext}`)
|
.map((ext) => `.${ext}`)
|
||||||
.filter((ext) => useTypeScript || !ext.includes('ts')),
|
.filter((ext) => useTypeScript || !ext.includes('ts')),
|
||||||
alias: {
|
alias: (() => {
|
||||||
// Support React Native Web
|
const defaultAlias = {
|
||||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
// Support React Native Web
|
||||||
'react-native': 'react-native-web',
|
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||||
// Allows for better profiling with ReactDevTools
|
'react-native': 'react-native-web',
|
||||||
...(isEnvProductionProfile && {
|
// Allows for better profiling with ReactDevTools
|
||||||
'react-dom$': 'react-dom/profiling',
|
...(isEnvProductionProfile && {
|
||||||
'scheduler/tracing': 'scheduler/tracing-profiling',
|
'react-dom$': 'react-dom/profiling',
|
||||||
}),
|
'scheduler/tracing': 'scheduler/tracing-profiling',
|
||||||
...(modules.webpackAliases || {}),
|
}),
|
||||||
'@': paths.appSrc,
|
...(modules.webpackAliases || {}),
|
||||||
'@project': paths.appRootSrc,
|
'bn.js': require.resolve('bn.js'),
|
||||||
'@oak-general-business': paths.oakGeneralBusinessPath,
|
assert: require.resolve('browser-assert'),
|
||||||
'@oak-frontend-base': paths.oakFrontendBasePath,
|
};
|
||||||
'@oak-app-domain': paths.oakAppDomainPath,
|
if (projectConfigration && projectConfigration.resolve && projectConfigration.resolve.alias) {
|
||||||
'bn.js': require.resolve('bn.js'),
|
Object.assign(defaultAlias, projectConfigration.resolve.alias);
|
||||||
assert: require.resolve('browser-assert'),
|
}
|
||||||
},
|
return defaultAlias;
|
||||||
|
})(),
|
||||||
plugins: [
|
plugins: [
|
||||||
// Prevents users from importing files from outside of src/ (or node_modules/).
|
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||||
// This often causes confusion because we only process files within src/ with babel.
|
// This often causes confusion because we only process files within src/ with babel.
|
||||||
|
|
@ -541,10 +553,10 @@ module.exports = function (webpackEnv) {
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
isEnvDevelopment &&
|
isEnvDevelopment &&
|
||||||
shouldUseReactRefresh &&
|
shouldUseReactRefresh &&
|
||||||
require.resolve(
|
require.resolve(
|
||||||
'react-refresh/babel'
|
'react-refresh/babel'
|
||||||
),
|
),
|
||||||
oakPathTsxPlugin,
|
oakPathTsxPlugin,
|
||||||
oakRenderTsxPlugin,
|
oakRenderTsxPlugin,
|
||||||
// oakRouterPlugin,
|
// oakRouterPlugin,
|
||||||
|
|
@ -759,14 +771,14 @@ module.exports = function (webpackEnv) {
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
isEnvProduction &&
|
isEnvProduction &&
|
||||||
new CompressionWebpackPlugin({
|
new CompressionWebpackPlugin({
|
||||||
filename: '[path][base].gz', //压缩后的文件名
|
filename: '[path][base].gz', //压缩后的文件名
|
||||||
algorithm: 'gzip', //压缩格式 有:gzip、brotliCompress
|
algorithm: 'gzip', //压缩格式 有:gzip、brotliCompress
|
||||||
test: /\.(js|css|svg)$/,
|
test: /\.(js|css|svg)$/,
|
||||||
threshold: 10240, // 只处理比这个值大的资源,按字节算
|
threshold: 10240, // 只处理比这个值大的资源,按字节算
|
||||||
minRatio: 0.8, //只有压缩率比这个值小的文件才会被处理,压缩率=压缩大小/原始大小,如果压缩后和原始文件大小没有太大区别,就不用压缩
|
minRatio: 0.8, //只有压缩率比这个值小的文件才会被处理,压缩率=压缩大小/原始大小,如果压缩后和原始文件大小没有太大区别,就不用压缩
|
||||||
deleteOriginalAssets: false, //是否删除原文件,最好不删除,服务器会自动优先返回同名的.gzip资源,如果找不到还可以拿原始文件
|
deleteOriginalAssets: false, //是否删除原文件,最好不删除,服务器会自动优先返回同名的.gzip资源,如果找不到还可以拿原始文件
|
||||||
}),
|
}),
|
||||||
// Generates an `index.html` file with the <script> injected.
|
// Generates an `index.html` file with the <script> injected.
|
||||||
new HtmlWebpackPlugin(
|
new HtmlWebpackPlugin(
|
||||||
Object.assign(
|
Object.assign(
|
||||||
|
|
@ -777,19 +789,19 @@ module.exports = function (webpackEnv) {
|
||||||
},
|
},
|
||||||
isEnvProduction
|
isEnvProduction
|
||||||
? {
|
? {
|
||||||
minify: {
|
minify: {
|
||||||
removeComments: true,
|
removeComments: true,
|
||||||
collapseWhitespace: true,
|
collapseWhitespace: true,
|
||||||
removeRedundantAttributes: true,
|
removeRedundantAttributes: true,
|
||||||
useShortDoctype: true,
|
useShortDoctype: true,
|
||||||
removeEmptyAttributes: true,
|
removeEmptyAttributes: true,
|
||||||
removeStyleLinkTypeAttributes: true,
|
removeStyleLinkTypeAttributes: true,
|
||||||
keepClosingSlash: true,
|
keepClosingSlash: true,
|
||||||
minifyJS: true,
|
minifyJS: true,
|
||||||
minifyCSS: true,
|
minifyCSS: true,
|
||||||
minifyURLs: true,
|
minifyURLs: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
@ -797,10 +809,10 @@ module.exports = function (webpackEnv) {
|
||||||
// a network request.
|
// a network request.
|
||||||
// https://github.com/facebook/create-react-app/issues/5358
|
// https://github.com/facebook/create-react-app/issues/5358
|
||||||
isEnvProduction &&
|
isEnvProduction &&
|
||||||
shouldInlineRuntimeChunk &&
|
shouldInlineRuntimeChunk &&
|
||||||
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [
|
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [
|
||||||
/runtime-.+[.]js/,
|
/runtime-.+[.]js/,
|
||||||
]),
|
]),
|
||||||
// Makes some environment variables available in index.html.
|
// Makes some environment variables available in index.html.
|
||||||
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||||
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
|
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
|
||||||
|
|
@ -819,22 +831,22 @@ module.exports = function (webpackEnv) {
|
||||||
// Experimental hot reloading for React .
|
// Experimental hot reloading for React .
|
||||||
// https://github.com/facebook/react/tree/main/packages/react-refresh
|
// https://github.com/facebook/react/tree/main/packages/react-refresh
|
||||||
isEnvDevelopment &&
|
isEnvDevelopment &&
|
||||||
shouldUseReactRefresh &&
|
shouldUseReactRefresh &&
|
||||||
new ReactRefreshWebpackPlugin({
|
new ReactRefreshWebpackPlugin({
|
||||||
overlay: false,
|
overlay: false,
|
||||||
}),
|
}),
|
||||||
// Watcher doesn't work well if you mistype casing in a path so we use
|
// Watcher doesn't work well if you mistype casing in a path so we use
|
||||||
// a plugin that prints an error when you attempt to do this.
|
// a plugin that prints an error when you attempt to do this.
|
||||||
// See https://github.com/facebook/create-react-app/issues/240
|
// See https://github.com/facebook/create-react-app/issues/240
|
||||||
isEnvDevelopment && new CaseSensitivePathsPlugin(),
|
isEnvDevelopment && new CaseSensitivePathsPlugin(),
|
||||||
isEnvProduction &&
|
isEnvProduction &&
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
// Options similar to the same options in webpackOptions.output
|
// Options similar to the same options in webpackOptions.output
|
||||||
// both options are optional
|
// both options are optional
|
||||||
filename: 'static/css/[name].[contenthash:8].css',
|
filename: 'static/css/[name].[contenthash:8].css',
|
||||||
chunkFilename:
|
chunkFilename:
|
||||||
'static/css/[name].[contenthash:8].chunk.css',
|
'static/css/[name].[contenthash:8].chunk.css',
|
||||||
}),
|
}),
|
||||||
// Generate an asset manifest file with the following content:
|
// Generate an asset manifest file with the following content:
|
||||||
// - "files" key: Mapping of all asset filenames to their corresponding
|
// - "files" key: Mapping of all asset filenames to their corresponding
|
||||||
// output file so that tools can pick it up without having to parse
|
// output file so that tools can pick it up without having to parse
|
||||||
|
|
@ -871,136 +883,136 @@ module.exports = function (webpackEnv) {
|
||||||
// Generate a service worker script that will precache, and keep up to date,
|
// Generate a service worker script that will precache, and keep up to date,
|
||||||
// the HTML & assets that are part of the webpack build.
|
// the HTML & assets that are part of the webpack build.
|
||||||
isEnvProduction &&
|
isEnvProduction &&
|
||||||
fs.existsSync(swSrc) &&
|
fs.existsSync(swSrc) &&
|
||||||
new WorkboxWebpackPlugin.InjectManifest({
|
new WorkboxWebpackPlugin.InjectManifest({
|
||||||
swSrc,
|
swSrc,
|
||||||
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
|
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
|
||||||
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
|
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
|
||||||
// Bump up the default maximum size (2mb) that's precached,
|
// Bump up the default maximum size (2mb) that's precached,
|
||||||
// to make lazy-loading failure scenarios less likely.
|
// to make lazy-loading failure scenarios less likely.
|
||||||
// See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
|
// See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
|
||||||
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
|
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
|
||||||
}),
|
}),
|
||||||
// TypeScript type checking
|
// TypeScript type checking
|
||||||
useTypeScript &&
|
useTypeScript &&
|
||||||
new ForkTsCheckerWebpackPlugin({
|
new ForkTsCheckerWebpackPlugin({
|
||||||
async: isEnvDevelopment,
|
async: isEnvDevelopment,
|
||||||
typescript: {
|
typescript: {
|
||||||
typescriptPath: resolve.sync('typescript', {
|
typescriptPath: resolve.sync('typescript', {
|
||||||
basedir: paths.appNodeModules,
|
basedir: paths.appNodeModules,
|
||||||
}),
|
}),
|
||||||
// configOverwrite: {
|
// configOverwrite: {
|
||||||
// compilerOptions: {
|
// compilerOptions: {
|
||||||
// sourceMap: isEnvProduction
|
// sourceMap: isEnvProduction
|
||||||
// ? shouldUseSourceMap
|
// ? shouldUseSourceMap
|
||||||
// : isEnvDevelopment,
|
// : isEnvDevelopment,
|
||||||
// skipLibCheck: true,
|
// skipLibCheck: true,
|
||||||
// inlineSourceMap: false,
|
// inlineSourceMap: false,
|
||||||
// declarationMap: false,
|
// declarationMap: false,
|
||||||
// noEmit: true,
|
// noEmit: true,
|
||||||
// incremental: true,
|
// incremental: true,
|
||||||
// tsBuildInfoFile: paths.appTsBuildInfoFile,
|
// tsBuildInfoFile: paths.appTsBuildInfoFile,
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
configFile: paths.appTsConfig,
|
configFile: paths.appTsConfig,
|
||||||
context: paths.appRootPath,
|
context: paths.appRootPath,
|
||||||
diagnosticOptions: {
|
diagnosticOptions: {
|
||||||
syntactic: true,
|
syntactic: true,
|
||||||
},
|
|
||||||
mode: 'write-references',
|
|
||||||
// profile: true,
|
|
||||||
memoryLimit,
|
|
||||||
},
|
},
|
||||||
issue: {
|
mode: 'write-references',
|
||||||
// This one is specifically to match during CI tests,
|
// profile: true,
|
||||||
// as micromatch doesn't match
|
memoryLimit,
|
||||||
// '../cra-template-typescript/template/src/App.tsx'
|
},
|
||||||
// otherwise.
|
issue: {
|
||||||
include: [
|
// This one is specifically to match during CI tests,
|
||||||
{ file: '../**/app/**/*.{ts,tsx}' },
|
// as micromatch doesn't match
|
||||||
{ file: '**/app/**/*.{ts,tsx}' },
|
// '../cra-template-typescript/template/src/App.tsx'
|
||||||
{ file: '../**/app/**/*.*.{ts,tsx}' },
|
// otherwise.
|
||||||
{ file: '**/app/**/*.*.{ts,tsx}' },
|
include: [
|
||||||
{ file: '../**/src/**/*.{ts,tsx}' },
|
{ file: '../**/app/**/*.{ts,tsx}' },
|
||||||
{ file: '**/src/**/*.{ts,tsx}' },
|
{ file: '**/app/**/*.{ts,tsx}' },
|
||||||
{ file: '../**/src/**/*.*.{ts,tsx}' },
|
{ file: '../**/app/**/*.*.{ts,tsx}' },
|
||||||
{ file: '**/src/**/*.*.{ts,tsx}' },
|
{ file: '**/app/**/*.*.{ts,tsx}' },
|
||||||
],
|
{ file: '../**/src/**/*.{ts,tsx}' },
|
||||||
exclude: [
|
{ file: '**/src/**/*.{ts,tsx}' },
|
||||||
{ file: '**/src/**/__tests__/**' },
|
{ file: '../**/src/**/*.*.{ts,tsx}' },
|
||||||
{ file: '**/src/**/?(*.){spec|test}.*' },
|
{ file: '**/src/**/*.*.{ts,tsx}' },
|
||||||
{ file: '**/src/setupProxy.*' },
|
],
|
||||||
{ file: '**/src/setupTests.*' },
|
exclude: [
|
||||||
],
|
{ file: '**/src/**/__tests__/**' },
|
||||||
},
|
{ file: '**/src/**/?(*.){spec|test}.*' },
|
||||||
logger: {
|
{ file: '**/src/setupProxy.*' },
|
||||||
log: (message) => console.log(message),
|
{ file: '**/src/setupTests.*' },
|
||||||
error: (message) => console.error(message),
|
],
|
||||||
},
|
},
|
||||||
}),
|
logger: {
|
||||||
|
log: (message) => console.log(message),
|
||||||
|
error: (message) => console.error(message),
|
||||||
|
},
|
||||||
|
}),
|
||||||
!disableESLintPlugin &&
|
!disableESLintPlugin &&
|
||||||
new ESLintPlugin({
|
new ESLintPlugin({
|
||||||
// Plugin options
|
// Plugin options
|
||||||
extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
|
extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
|
||||||
formatter: require.resolve(
|
formatter: require.resolve(
|
||||||
'react-dev-utils/eslintFormatter'
|
'react-dev-utils/eslintFormatter'
|
||||||
),
|
),
|
||||||
eslintPath: require.resolve('eslint'),
|
eslintPath: require.resolve('eslint'),
|
||||||
failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
|
failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
|
||||||
context: paths.appSrc,
|
context: paths.appSrc,
|
||||||
cache: true,
|
cache: true,
|
||||||
cacheLocation: path.resolve(
|
cacheLocation: path.resolve(
|
||||||
paths.appNodeModules,
|
paths.appNodeModules,
|
||||||
'.cache/.eslintcache'
|
'.cache/.eslintcache'
|
||||||
),
|
),
|
||||||
// ESLint class options
|
// ESLint class options
|
||||||
cwd: paths.appPath,
|
cwd: paths.appPath,
|
||||||
resolvePluginsRelativeTo: __dirname,
|
resolvePluginsRelativeTo: __dirname,
|
||||||
baseConfig: {
|
baseConfig: {
|
||||||
extends: [
|
extends: [
|
||||||
require.resolve('eslint-config-react-app/base'),
|
require.resolve('eslint-config-react-app/base'),
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
...(!hasJsxRuntime && {
|
...(!hasJsxRuntime && {
|
||||||
'react/react-in-jsx-scope': 'error',
|
'react/react-in-jsx-scope': 'error',
|
||||||
}),
|
}),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
|
}),
|
||||||
new webpack.ProvidePlugin({
|
new webpack.ProvidePlugin({
|
||||||
Buffer: ['buffer', 'Buffer'],
|
Buffer: ['buffer', 'Buffer'],
|
||||||
}),
|
}),
|
||||||
shouldAnalyze &&
|
shouldAnalyze &&
|
||||||
new BundleAnalyzerPlugin({
|
new BundleAnalyzerPlugin({
|
||||||
// 可以是`server`,`static`或`disabled`。
|
// 可以是`server`,`static`或`disabled`。
|
||||||
// 在`server`模式下,分析器将启动HTTP服务器来显示软件包报告。
|
// 在`server`模式下,分析器将启动HTTP服务器来显示软件包报告。
|
||||||
// 在“静态”模式下,会生成带有报告的单个HTML文件。
|
// 在“静态”模式下,会生成带有报告的单个HTML文件。
|
||||||
// 在`disabled`模式下,你可以使用这个插件来将`generateStatsFile`设置为`true`来生成Webpack Stats JSON文件。
|
// 在`disabled`模式下,你可以使用这个插件来将`generateStatsFile`设置为`true`来生成Webpack Stats JSON文件。
|
||||||
analyzerMode: 'server',
|
analyzerMode: 'server',
|
||||||
// 将在“服务器”模式下使用的主机启动HTTP服务器。
|
// 将在“服务器”模式下使用的主机启动HTTP服务器。
|
||||||
analyzerHost: '127.0.0.1',
|
analyzerHost: '127.0.0.1',
|
||||||
// 将在“服务器”模式下使用的端口启动HTTP服务器。
|
// 将在“服务器”模式下使用的端口启动HTTP服务器。
|
||||||
analyzerPort: 8888,
|
analyzerPort: 8888,
|
||||||
// 路径捆绑,将在`static`模式下生成的报告文件。
|
// 路径捆绑,将在`static`模式下生成的报告文件。
|
||||||
// 相对于捆绑输出目录。
|
// 相对于捆绑输出目录。
|
||||||
reportFilename: 'report.html',
|
reportFilename: 'report.html',
|
||||||
// 模块大小默认显示在报告中。
|
// 模块大小默认显示在报告中。
|
||||||
// 应该是`stat`,`parsed`或者`gzip`中的一个。
|
// 应该是`stat`,`parsed`或者`gzip`中的一个。
|
||||||
// 有关更多信息,请参见“定义”一节。
|
// 有关更多信息,请参见“定义”一节。
|
||||||
defaultSizes: 'parsed',
|
defaultSizes: 'parsed',
|
||||||
// 在默认浏览器中自动打开报告
|
// 在默认浏览器中自动打开报告
|
||||||
openAnalyzer: true,
|
openAnalyzer: true,
|
||||||
// 如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成
|
// 如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成
|
||||||
generateStatsFile: false,
|
generateStatsFile: false,
|
||||||
// 如果`generateStatsFile`为`true`,将会生成Webpack Stats JSON文件的名字。
|
// 如果`generateStatsFile`为`true`,将会生成Webpack Stats JSON文件的名字。
|
||||||
// 相对于捆绑输出目录。
|
// 相对于捆绑输出目录。
|
||||||
statsFilename: 'stats.json',
|
statsFilename: 'stats.json',
|
||||||
// stats.toJson()方法的选项。
|
// stats.toJson()方法的选项。
|
||||||
// 例如,您可以使用`source:false`选项排除统计文件中模块的来源。
|
// 例如,您可以使用`source:false`选项排除统计文件中模块的来源。
|
||||||
// 在这里查看更多选项:https: //github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
|
// 在这里查看更多选项:https: //github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
|
||||||
statsOptions: null,
|
statsOptions: null,
|
||||||
logLevel: 'info',
|
logLevel: 'info',
|
||||||
}),
|
}),
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
// Turn off performance processing because we utilize
|
// Turn off performance processing because we utilize
|
||||||
// our own hints via the FileSizeReporter
|
// our own hints via the FileSizeReporter
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// import { CompilerConfiguration } from 'oak-domain/lib/types/Configuration';
|
||||||
|
const path = require('path');
|
||||||
|
module.exports = {
|
||||||
|
webpack: {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@project': path.resolve('src'),
|
||||||
|
'@oak-app-domain': path.resolve('src', 'oak-app-domain'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
import { EntityDict } from '@project/oak-app-domain';
|
||||||
|
import { Feature } from 'oak-frontend-base';
|
||||||
|
import { CommonAspectDict } from 'oak-common-aspect';
|
||||||
|
import { AspectDict } from '../aspects/AspectDict';
|
||||||
|
import { BackendRuntimeContext } from '@project/context/BackendRuntimeContext';
|
||||||
|
import { FrontendRuntimeContext } from '@project/context/FrontendRuntimeContext';
|
||||||
|
import { groupBy } from 'oak-domain/lib/utils/lodash';
|
||||||
|
import { ContextMenuFactory } from 'oak-frontend-base/es/features/contextMenuFactory';
|
||||||
|
import Console from './Console';
|
||||||
|
|
||||||
|
type GroupName = 'System';
|
||||||
|
|
||||||
|
type Groups = {
|
||||||
|
icon: string;
|
||||||
|
name: GroupName;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
interface IMenu<T extends keyof EntityDict> {
|
||||||
|
name: string;
|
||||||
|
icon: string;
|
||||||
|
url: string;
|
||||||
|
entity?: T;
|
||||||
|
paths?: string[];
|
||||||
|
action?: EntityDict[T]['Action'];
|
||||||
|
parent?: GroupName;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface OMenu {
|
||||||
|
name: GroupName | string;
|
||||||
|
icon: string;
|
||||||
|
url?: string;
|
||||||
|
children?: Array<OMenu>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const groups: Groups = [
|
||||||
|
{
|
||||||
|
name: 'System', // 系统级别配置
|
||||||
|
icon: 'setup_fill',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const menus: IMenu<keyof EntityDict>[] = [
|
||||||
|
{
|
||||||
|
name: 'Dashboard',
|
||||||
|
icon: 'document',
|
||||||
|
url: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'relationManage',
|
||||||
|
icon: 'share',
|
||||||
|
url: '/relation/entityList',
|
||||||
|
parent: 'System',
|
||||||
|
entity: 'relation',
|
||||||
|
action: 'create',
|
||||||
|
paths: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default class Menu extends Feature {
|
||||||
|
private contextMenuFactory: ContextMenuFactory<EntityDict,
|
||||||
|
BackendRuntimeContext,
|
||||||
|
FrontendRuntimeContext,
|
||||||
|
AspectDict & CommonAspectDict<EntityDict, BackendRuntimeContext>>;
|
||||||
|
private console: Console;
|
||||||
|
private menus?: OMenu[];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
contextMenuFactory: ContextMenuFactory<EntityDict,
|
||||||
|
BackendRuntimeContext,
|
||||||
|
FrontendRuntimeContext,
|
||||||
|
AspectDict & CommonAspectDict<EntityDict, BackendRuntimeContext>>,
|
||||||
|
console: Console
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
this.contextMenuFactory = contextMenuFactory;
|
||||||
|
this.contextMenuFactory.setMenus(menus);
|
||||||
|
this.console = console;
|
||||||
|
this.console.subscribe(
|
||||||
|
() => {
|
||||||
|
this.refreshMenus();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshMenus() {
|
||||||
|
const roomId = this.console.getRoomId();
|
||||||
|
const menus = this.contextMenuFactory.getMenusByContext<IMenu<keyof EntityDict>>('room', roomId);
|
||||||
|
const menuGroup = groupBy(menus, 'parent');
|
||||||
|
this.menus = (menus as any[]).filter(ele => !ele.parent).concat(
|
||||||
|
groups.map((ele) => {
|
||||||
|
const { name, icon } = ele;
|
||||||
|
const children = menuGroup[name];
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
icon,
|
||||||
|
children,
|
||||||
|
};
|
||||||
|
}).filter((ele) => !!ele.children)
|
||||||
|
);
|
||||||
|
this.publish();
|
||||||
|
}
|
||||||
|
|
||||||
|
getMenus() {
|
||||||
|
if (!this.menus) {
|
||||||
|
this.refreshMenus();
|
||||||
|
}
|
||||||
|
return this.menus;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue