2.2.0 (#1188)
2.2.0 / 2019-12-22
==================
## Notice
2.2.0 focuses on updating the front end of CTFd to use more modern programming practices and changes some aspects of core CTFd design. If your current installation is using a custom theme or custom plugin with ***any*** kind of JavaScript, it is likely that you will need to upgrade that theme/plugin to be useable with v2.2.0.
**General**
* Team size limits can now be enforced from the configuration panel
* Access tokens functionality for API usage
* Admins can now choose how to deliver their notifications
* Toast (new default)
* Alert
* Background
* Sound On / Sound Off
* There is now a notification counter showing how many unread notifications were received
* Setup has been redesigned to have multiple steps
* Added Description
* Added Start time and End time,
* Added MajorLeagueCyber integration
* Added Theme and color selection
* Fixes issue where updating dynamic challenges could change the value to an incorrect value
* Properly use a less restrictive regex to validate email addresses
* Bump Python dependencies to latest working versions
* Admins can now give awards to team members from the team's admin panel page
**API**
* Team member removals (`DELETE /api/v1/teams/[team_id]/members`) from the admin panel will now delete the removed members's Submissions, Awards, Unlocks
**Admin Panel**
* Admins can now user a color input box to specify a theme color which is injected as part of the CSS configuration. Theme developers can use this CSS value to change colors and styles accordingly.
* Challenge updates will now alert you if the challenge doesn't have a flag
* Challenge entry now allows you to upload files and enter simple flags from the initial challenge creation page
**Themes**
* Significant JavaScript and CSS rewrite to use ES6, Webpack, yarn, and babel
* Theme asset specially generated URLs
* Static theme assets are now loaded with either .dev.extension or .min.extension depending on production or development (i.e. debug server)
* Static theme assets are also given a `d` GET parameter that changes per server start. Used to bust browser caches.
* Use `defer` for script tags to not block page rendering
* Only show the MajorLeagueCyber button if configured in configuration
* The admin panel now links to https://help.ctfd.io/ in the top right
* Create an `ezToast()` function to use [Bootstrap's toasts](https://getbootstrap.com/docs/4.3/components/toasts/)
* The user-facing navbar now features icons
* Awards shown on a user's profile can now have award icons
* The default MarkdownIt render created by CTFd will now open links in new tabs
* Country flags can now be shown on the user pages
**Deployment**
* Switch `Dockerfile` from `python:2.7-alpine` to `python:3.7-alpine`
* Add `SERVER_SENT_EVENTS` config value to control whether Notifications are enabled
* Challenge ID is now recorded in the submission log
**Plugins**
* Add an endpoint parameter to `register_plugin_assets_directory()` and `register_plugin_asset()` to control what endpoint Flask uses for the added route
**Miscellaneous**
* `CTFd.utils.email.sendmail()` now allows the caller to specify subject as an argument
* The subject allows for injecting custom variable via the new `CTFd.utils.formatters.safe_format()` function
* Admin user information is now error checked during setup
* Added yarn to the toolchain and the yarn dev, yarn build, yarn verify, and yarn clean scripts
* Prevent old CTFd imports from being imported
2019-12-23 04:17:34 +00:00
|
|
|
const path = require('path')
|
|
|
|
const webpack = require('webpack')
|
|
|
|
const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries")
|
|
|
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
|
|
|
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
|
|
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
|
|
|
const RemoveStrictPlugin = require('remove-strict-webpack-plugin')
|
|
|
|
const WebpackShellPlugin = require('webpack-shell-plugin');
|
|
|
|
|
|
|
|
const roots = {
|
|
|
|
'themes/core': {
|
|
|
|
'css': {
|
|
|
|
'challenge-board': 'assets/css/challenge-board.scss',
|
|
|
|
'fonts': 'assets/css/fonts.scss',
|
|
|
|
'main': 'assets/css/main.scss',
|
|
|
|
'core': 'assets/css/core.scss',
|
|
|
|
'codemirror': 'assets/css/codemirror.scss',
|
|
|
|
},
|
|
|
|
'js': {
|
|
|
|
'pages/main': 'assets/js/pages/main.js',
|
|
|
|
'pages/setup': 'assets/js/pages/setup.js',
|
|
|
|
'pages/challenges': 'assets/js/pages/challenges.js',
|
|
|
|
'pages/scoreboard': 'assets/js/pages/scoreboard.js',
|
|
|
|
'pages/settings': 'assets/js/pages/settings.js',
|
|
|
|
'pages/stats': 'assets/js/pages/stats.js',
|
|
|
|
'pages/notifications': 'assets/js/pages/notifications.js',
|
|
|
|
'pages/teams/private': 'assets/js/pages/teams/private.js',
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'themes/admin': {
|
|
|
|
'css': {
|
|
|
|
'admin': 'assets/css/admin.scss',
|
|
|
|
'challenge-board': 'assets/css/challenge-board.scss',
|
2020-01-04 03:18:05 +00:00
|
|
|
'codemirror': 'assets/css/codemirror.scss',
|
2.2.0 (#1188)
2.2.0 / 2019-12-22
==================
## Notice
2.2.0 focuses on updating the front end of CTFd to use more modern programming practices and changes some aspects of core CTFd design. If your current installation is using a custom theme or custom plugin with ***any*** kind of JavaScript, it is likely that you will need to upgrade that theme/plugin to be useable with v2.2.0.
**General**
* Team size limits can now be enforced from the configuration panel
* Access tokens functionality for API usage
* Admins can now choose how to deliver their notifications
* Toast (new default)
* Alert
* Background
* Sound On / Sound Off
* There is now a notification counter showing how many unread notifications were received
* Setup has been redesigned to have multiple steps
* Added Description
* Added Start time and End time,
* Added MajorLeagueCyber integration
* Added Theme and color selection
* Fixes issue where updating dynamic challenges could change the value to an incorrect value
* Properly use a less restrictive regex to validate email addresses
* Bump Python dependencies to latest working versions
* Admins can now give awards to team members from the team's admin panel page
**API**
* Team member removals (`DELETE /api/v1/teams/[team_id]/members`) from the admin panel will now delete the removed members's Submissions, Awards, Unlocks
**Admin Panel**
* Admins can now user a color input box to specify a theme color which is injected as part of the CSS configuration. Theme developers can use this CSS value to change colors and styles accordingly.
* Challenge updates will now alert you if the challenge doesn't have a flag
* Challenge entry now allows you to upload files and enter simple flags from the initial challenge creation page
**Themes**
* Significant JavaScript and CSS rewrite to use ES6, Webpack, yarn, and babel
* Theme asset specially generated URLs
* Static theme assets are now loaded with either .dev.extension or .min.extension depending on production or development (i.e. debug server)
* Static theme assets are also given a `d` GET parameter that changes per server start. Used to bust browser caches.
* Use `defer` for script tags to not block page rendering
* Only show the MajorLeagueCyber button if configured in configuration
* The admin panel now links to https://help.ctfd.io/ in the top right
* Create an `ezToast()` function to use [Bootstrap's toasts](https://getbootstrap.com/docs/4.3/components/toasts/)
* The user-facing navbar now features icons
* Awards shown on a user's profile can now have award icons
* The default MarkdownIt render created by CTFd will now open links in new tabs
* Country flags can now be shown on the user pages
**Deployment**
* Switch `Dockerfile` from `python:2.7-alpine` to `python:3.7-alpine`
* Add `SERVER_SENT_EVENTS` config value to control whether Notifications are enabled
* Challenge ID is now recorded in the submission log
**Plugins**
* Add an endpoint parameter to `register_plugin_assets_directory()` and `register_plugin_asset()` to control what endpoint Flask uses for the added route
**Miscellaneous**
* `CTFd.utils.email.sendmail()` now allows the caller to specify subject as an argument
* The subject allows for injecting custom variable via the new `CTFd.utils.formatters.safe_format()` function
* Admin user information is now error checked during setup
* Added yarn to the toolchain and the yarn dev, yarn build, yarn verify, and yarn clean scripts
* Prevent old CTFd imports from being imported
2019-12-23 04:17:34 +00:00
|
|
|
},
|
|
|
|
'js': {
|
|
|
|
'pages/main': 'assets/js/pages/main.js',
|
|
|
|
'pages/challenge': 'assets/js/pages/challenge.js',
|
2020-04-22 22:49:57 +00:00
|
|
|
'pages/challenges': 'assets/js/pages/challenges.js',
|
2.2.0 (#1188)
2.2.0 / 2019-12-22
==================
## Notice
2.2.0 focuses on updating the front end of CTFd to use more modern programming practices and changes some aspects of core CTFd design. If your current installation is using a custom theme or custom plugin with ***any*** kind of JavaScript, it is likely that you will need to upgrade that theme/plugin to be useable with v2.2.0.
**General**
* Team size limits can now be enforced from the configuration panel
* Access tokens functionality for API usage
* Admins can now choose how to deliver their notifications
* Toast (new default)
* Alert
* Background
* Sound On / Sound Off
* There is now a notification counter showing how many unread notifications were received
* Setup has been redesigned to have multiple steps
* Added Description
* Added Start time and End time,
* Added MajorLeagueCyber integration
* Added Theme and color selection
* Fixes issue where updating dynamic challenges could change the value to an incorrect value
* Properly use a less restrictive regex to validate email addresses
* Bump Python dependencies to latest working versions
* Admins can now give awards to team members from the team's admin panel page
**API**
* Team member removals (`DELETE /api/v1/teams/[team_id]/members`) from the admin panel will now delete the removed members's Submissions, Awards, Unlocks
**Admin Panel**
* Admins can now user a color input box to specify a theme color which is injected as part of the CSS configuration. Theme developers can use this CSS value to change colors and styles accordingly.
* Challenge updates will now alert you if the challenge doesn't have a flag
* Challenge entry now allows you to upload files and enter simple flags from the initial challenge creation page
**Themes**
* Significant JavaScript and CSS rewrite to use ES6, Webpack, yarn, and babel
* Theme asset specially generated URLs
* Static theme assets are now loaded with either .dev.extension or .min.extension depending on production or development (i.e. debug server)
* Static theme assets are also given a `d` GET parameter that changes per server start. Used to bust browser caches.
* Use `defer` for script tags to not block page rendering
* Only show the MajorLeagueCyber button if configured in configuration
* The admin panel now links to https://help.ctfd.io/ in the top right
* Create an `ezToast()` function to use [Bootstrap's toasts](https://getbootstrap.com/docs/4.3/components/toasts/)
* The user-facing navbar now features icons
* Awards shown on a user's profile can now have award icons
* The default MarkdownIt render created by CTFd will now open links in new tabs
* Country flags can now be shown on the user pages
**Deployment**
* Switch `Dockerfile` from `python:2.7-alpine` to `python:3.7-alpine`
* Add `SERVER_SENT_EVENTS` config value to control whether Notifications are enabled
* Challenge ID is now recorded in the submission log
**Plugins**
* Add an endpoint parameter to `register_plugin_assets_directory()` and `register_plugin_asset()` to control what endpoint Flask uses for the added route
**Miscellaneous**
* `CTFd.utils.email.sendmail()` now allows the caller to specify subject as an argument
* The subject allows for injecting custom variable via the new `CTFd.utils.formatters.safe_format()` function
* Admin user information is now error checked during setup
* Added yarn to the toolchain and the yarn dev, yarn build, yarn verify, and yarn clean scripts
* Prevent old CTFd imports from being imported
2019-12-23 04:17:34 +00:00
|
|
|
'pages/configs': 'assets/js/pages/configs.js',
|
|
|
|
'pages/notifications': 'assets/js/pages/notifications.js',
|
|
|
|
'pages/editor': 'assets/js/pages/editor.js',
|
|
|
|
'pages/pages': 'assets/js/pages/pages.js',
|
|
|
|
'pages/reset': 'assets/js/pages/reset.js',
|
|
|
|
'pages/scoreboard': 'assets/js/pages/scoreboard.js',
|
|
|
|
'pages/statistics': 'assets/js/pages/statistics.js',
|
|
|
|
'pages/submissions': 'assets/js/pages/submissions.js',
|
|
|
|
'pages/team': 'assets/js/pages/team.js',
|
|
|
|
'pages/teams': 'assets/js/pages/teams.js',
|
|
|
|
'pages/user': 'assets/js/pages/user.js',
|
|
|
|
'pages/users': 'assets/js/pages/users.js',
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
function getJSConfig(root, type, entries, mode) {
|
|
|
|
const out = {}
|
|
|
|
const ext = mode == 'development' ? 'dev' : 'min'
|
|
|
|
const chunk_file = `[name].${ext}.chunk.js`
|
|
|
|
|
|
|
|
for (let key in entries) {
|
|
|
|
out[key] = path.resolve(__dirname, 'CTFd', root, entries[key])
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
entry: out,
|
|
|
|
output: {
|
|
|
|
path: path.resolve(__dirname, 'CTFd', root, 'static', type),
|
|
|
|
publicPath: '/' + root + '/static/' + type,
|
|
|
|
filename: `[name].${ext}.js`,
|
|
|
|
chunkFilename: chunk_file,
|
|
|
|
},
|
|
|
|
optimization: {
|
|
|
|
splitChunks: {
|
|
|
|
chunks: 'all',
|
|
|
|
cacheGroups: {
|
|
|
|
plotly: {
|
|
|
|
name: 'plotly',
|
|
|
|
filename: `plotly.bundle.${ext}.js`,
|
|
|
|
test: /plotly/,
|
|
|
|
priority: 1,
|
|
|
|
enforce: true,
|
|
|
|
},
|
|
|
|
vendor: {
|
|
|
|
name: 'vendor',
|
|
|
|
filename: `vendor.bundle.${ext}.js`,
|
|
|
|
test: /node_modules/,
|
|
|
|
// maxSize: 1024 * 256,
|
|
|
|
enforce: true,
|
|
|
|
},
|
|
|
|
graphs: {
|
|
|
|
name: 'graphs',
|
|
|
|
filename: `graphs.${ext}.js`,
|
|
|
|
test: /graphs/,
|
|
|
|
priority: 1,
|
|
|
|
reuseExistingChunk: true,
|
|
|
|
},
|
|
|
|
helpers: {
|
|
|
|
name: 'helpers',
|
|
|
|
filename: `helpers.${ext}.js`,
|
|
|
|
test: /helpers/,
|
|
|
|
priority: 1,
|
|
|
|
reuseExistingChunk: true,
|
|
|
|
},
|
|
|
|
default: {
|
|
|
|
filename: `core.${ext}.js`,
|
|
|
|
minChunks: 2,
|
|
|
|
priority: -1,
|
|
|
|
reuseExistingChunk: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
minimizer: [
|
|
|
|
new UglifyJsPlugin({
|
|
|
|
cache: true,
|
|
|
|
parallel: true,
|
|
|
|
sourceMap: true
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
},
|
|
|
|
module: {
|
|
|
|
rules: [
|
|
|
|
{
|
|
|
|
test: /\.js$/,
|
|
|
|
use: {
|
|
|
|
loader: 'babel-loader',
|
|
|
|
options: {
|
|
|
|
cacheDirectory: true,
|
|
|
|
presets: [
|
|
|
|
['@babel/preset-env', { useBuiltIns: 'entry', modules: 'commonjs' }],
|
|
|
|
],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
plugins: [
|
|
|
|
new webpack.NamedModulesPlugin(),
|
|
|
|
new RemoveStrictPlugin(),
|
|
|
|
// Identify files that are generated in development but not in production and create stubs to avoid a 404
|
|
|
|
// Pretty nasty hack, would be a little better if this was purely JS
|
|
|
|
new WebpackShellPlugin({
|
|
|
|
onBuildEnd:[
|
2020-02-29 20:21:22 +00:00
|
|
|
mode == 'development' ? 'echo Skipping JS stub generation' : 'python3 -c \'exec(\"\"\"\nimport glob\nimport os\n\nstatic_js_dirs = [\n "CTFd/themes/core/static/js/**/*.dev.js",\n "CTFd/themes/admin/static/js/**/*.dev.js",\n]\n\nfor js_dir in static_js_dirs:\n for path in glob.glob(js_dir, recursive=True):\n if path.endswith(".dev.js"):\n path = path.replace(".dev.js", ".min.js")\n if os.path.isfile(path) is False:\n open(path, "a").close()\n\"\"\")\''
|
2.2.0 (#1188)
2.2.0 / 2019-12-22
==================
## Notice
2.2.0 focuses on updating the front end of CTFd to use more modern programming practices and changes some aspects of core CTFd design. If your current installation is using a custom theme or custom plugin with ***any*** kind of JavaScript, it is likely that you will need to upgrade that theme/plugin to be useable with v2.2.0.
**General**
* Team size limits can now be enforced from the configuration panel
* Access tokens functionality for API usage
* Admins can now choose how to deliver their notifications
* Toast (new default)
* Alert
* Background
* Sound On / Sound Off
* There is now a notification counter showing how many unread notifications were received
* Setup has been redesigned to have multiple steps
* Added Description
* Added Start time and End time,
* Added MajorLeagueCyber integration
* Added Theme and color selection
* Fixes issue where updating dynamic challenges could change the value to an incorrect value
* Properly use a less restrictive regex to validate email addresses
* Bump Python dependencies to latest working versions
* Admins can now give awards to team members from the team's admin panel page
**API**
* Team member removals (`DELETE /api/v1/teams/[team_id]/members`) from the admin panel will now delete the removed members's Submissions, Awards, Unlocks
**Admin Panel**
* Admins can now user a color input box to specify a theme color which is injected as part of the CSS configuration. Theme developers can use this CSS value to change colors and styles accordingly.
* Challenge updates will now alert you if the challenge doesn't have a flag
* Challenge entry now allows you to upload files and enter simple flags from the initial challenge creation page
**Themes**
* Significant JavaScript and CSS rewrite to use ES6, Webpack, yarn, and babel
* Theme asset specially generated URLs
* Static theme assets are now loaded with either .dev.extension or .min.extension depending on production or development (i.e. debug server)
* Static theme assets are also given a `d` GET parameter that changes per server start. Used to bust browser caches.
* Use `defer` for script tags to not block page rendering
* Only show the MajorLeagueCyber button if configured in configuration
* The admin panel now links to https://help.ctfd.io/ in the top right
* Create an `ezToast()` function to use [Bootstrap's toasts](https://getbootstrap.com/docs/4.3/components/toasts/)
* The user-facing navbar now features icons
* Awards shown on a user's profile can now have award icons
* The default MarkdownIt render created by CTFd will now open links in new tabs
* Country flags can now be shown on the user pages
**Deployment**
* Switch `Dockerfile` from `python:2.7-alpine` to `python:3.7-alpine`
* Add `SERVER_SENT_EVENTS` config value to control whether Notifications are enabled
* Challenge ID is now recorded in the submission log
**Plugins**
* Add an endpoint parameter to `register_plugin_assets_directory()` and `register_plugin_asset()` to control what endpoint Flask uses for the added route
**Miscellaneous**
* `CTFd.utils.email.sendmail()` now allows the caller to specify subject as an argument
* The subject allows for injecting custom variable via the new `CTFd.utils.formatters.safe_format()` function
* Admin user information is now error checked during setup
* Added yarn to the toolchain and the yarn dev, yarn build, yarn verify, and yarn clean scripts
* Prevent old CTFd imports from being imported
2019-12-23 04:17:34 +00:00
|
|
|
],
|
|
|
|
safe: true,
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
resolve: {
|
|
|
|
extensions: ['.js'],
|
|
|
|
alias: {
|
|
|
|
core: path.resolve(__dirname, 'CTFd/themes/core/assets/js/'),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCSSConfig(root, type, entries, mode) {
|
|
|
|
const out = {}
|
|
|
|
const ext = mode == 'development' ? 'dev' : 'min'
|
|
|
|
const ouptut_file = `[name].${ext}.css`
|
|
|
|
const chunk_file = `[id].${ext}.css`
|
|
|
|
|
|
|
|
for (let key in entries) {
|
|
|
|
out[key] = path.resolve(__dirname, 'CTFd', root, entries[key])
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
entry: out,
|
|
|
|
output: {
|
|
|
|
path: path.resolve(__dirname, 'CTFd', root, 'static', type),
|
|
|
|
publicPath: '/' + root + '/static/' + type,
|
|
|
|
},
|
|
|
|
optimization: {
|
|
|
|
minimizer: [
|
|
|
|
new OptimizeCssAssetsPlugin({})
|
|
|
|
]
|
|
|
|
},
|
|
|
|
module: {
|
|
|
|
rules: [
|
|
|
|
{
|
|
|
|
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?(#\w+)?$/,
|
|
|
|
use: [
|
|
|
|
{
|
|
|
|
loader: 'file-loader',
|
|
|
|
options: {
|
|
|
|
name: '[name].[ext]',
|
|
|
|
publicPath: '../fonts',
|
|
|
|
outputPath: '../fonts',
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.(s?)css$/,
|
|
|
|
use: [
|
|
|
|
MiniCssExtractPlugin.loader,
|
|
|
|
{
|
|
|
|
loader: 'css-loader',
|
|
|
|
options: {
|
|
|
|
importLoaders: 2,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
loader: 'string-replace-loader',
|
|
|
|
options: {
|
|
|
|
multiple: [
|
|
|
|
// Replace core font-faces
|
|
|
|
{ search: "font-face\s*{\s*font-family:\s*[\"']Lato[\"']", replace: "font-face{font-family:'LatoOffline'", flags: 'gm' },
|
|
|
|
{ search: "font-face\s*{\s*font-family:\s*[\"']Raleway[\"']", replace: "font-face{font-family:'RalewayOffline'", flags: 'gm' },
|
|
|
|
// Replace Font-Awesome font-faces
|
|
|
|
{ search: "font-face\s*{\s*font-family:\s*[\"']Font Awesome 5 Free[\"']", replace: "font-face{font-family:'Font Awesome 5 Free Offline'", flags: 'gm' },
|
|
|
|
{ search: "font-face\s*{\s*font-family:\s*[\"']Font Awesome 5 Brands[\"']", replace: "font-face{font-family:'Font Awesome 5 Brands Offline'", flags: 'gm' },
|
|
|
|
// Replace Font-Awesome class rules
|
|
|
|
{ search: "far\s*{\s*font-family:\s*[\"']Font Awesome 5 Free[\"']", replace: "far{font-family:'Font Awesome 5 Free','Font Awesome 5 Free Offline'", flags: 'gm' },
|
|
|
|
{ search: "fas\s*{\s*font-family:\s*[\"']Font Awesome 5 Free[\"']", replace: "fas{font-family:'Font Awesome 5 Free','Font Awesome 5 Free Offline'", flags: 'gm' },
|
|
|
|
{ search: "fab\s*{\s*font-family:\s*[\"']Font Awesome 5 Brands[\"']", replace: "fab{font-family:'Font Awesome 5 Brands','Font Awesome 5 Brands Offline'", flags: 'gm' },
|
|
|
|
],
|
|
|
|
strict: true,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
loader: 'sass-loader',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
]
|
|
|
|
},
|
|
|
|
resolve: {
|
|
|
|
extensions: ['.css'],
|
|
|
|
alias: {
|
|
|
|
core: path.resolve(__dirname, 'CTFd/themes/core/assets/css/'),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
plugins: [
|
|
|
|
new FixStyleOnlyEntriesPlugin(),
|
|
|
|
new MiniCssExtractPlugin({
|
|
|
|
filename: ouptut_file,
|
|
|
|
chunkFilename: chunk_file
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const mapping = {
|
|
|
|
'js': getJSConfig,
|
|
|
|
'css': getCSSConfig,
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = (env, options) => {
|
|
|
|
let output = []
|
|
|
|
let mode = options.mode
|
|
|
|
for (let root in roots) {
|
|
|
|
for (let type in roots[root]) {
|
|
|
|
let entry = mapping[type](root, type, roots[root][type], mode);
|
|
|
|
output.push(entry)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return output
|
|
|
|
}
|