diff options
Diffstat (limited to 'config/webpack')
-rw-r--r-- | config/webpack/custom/rules.js | 90 | ||||
-rw-r--r-- | config/webpack/development.js | 5 | ||||
-rw-r--r-- | config/webpack/environment.js | 43 | ||||
-rw-r--r-- | config/webpack/gitlab.js | 68 | ||||
-rw-r--r-- | config/webpack/production.js | 24 | ||||
-rw-r--r-- | config/webpack/test.js | 5 |
6 files changed, 235 insertions, 0 deletions
diff --git a/config/webpack/custom/rules.js b/config/webpack/custom/rules.js new file mode 100644 index 00000000000..2e9780abfb6 --- /dev/null +++ b/config/webpack/custom/rules.js @@ -0,0 +1,90 @@ +const path = require('path'); +const ROOT_PATH = path.resolve(__dirname, '../../../'); +const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache'); +const VUE_VERSION = require('vue/package.json').version; +const VUE_LOADER_VERSION = require('vue-loader/package.json').version; +const IS_DEV_SERVER = process.env.NODE_ENV === 'development'; + +module.exports = [ + { + type: 'javascript/auto', + test: /\.mjs$/, + use: [], + }, + { + test: /\.js$/, + exclude: path => /node_modules|vendor[\\/]assets/.test(path) && !/\.vue\.js/.test(path), + loader: 'babel-loader', + options: { + cacheDirectory: path.join(CACHE_PATH, 'babel-loader'), + }, + }, + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + cacheDirectory: path.join(CACHE_PATH, 'vue-loader'), + cacheIdentifier: [ + process.env.NODE_ENV || 'development', + process.version, + VUE_VERSION, + VUE_LOADER_VERSION, + ].join('|'), + }, + }, + { + test: /\.(graphql|gql)$/, + exclude: /node_modules/, + loader: 'graphql-tag/loader', + }, + { + test: /\.svg$/, + loader: 'raw-loader', + }, + { + test: /\.(gif|png)$/, + loader: 'url-loader', + options: {limit: 2048}, + }, + { + test: /\_worker\.js$/, + use: [ + { + loader: 'worker-loader', + options: { + name: '[name].[hash:8].worker.js', + inline: IS_DEV_SERVER, + }, + }, + 'babel-loader', + ], + }, + { + test: /\.(worker(\.min)?\.js|pdf|bmpr)$/, + exclude: /node_modules/, + loader: 'file-loader', + options: { + name: '[name].[hash:8].[ext]', + }, + }, + { + test: /.css$/, + use: [ + 'vue-style-loader', + { + loader: 'css-loader', + options: { + name: '[name].[hash:8].[ext]', + }, + }, + ], + }, + { + test: /\.(eot|ttf|woff|woff2)$/, + include: /node_modules\/katex\/dist\/fonts/, + loader: 'file-loader', + options: { + name: '[name].[hash:8].[ext]', + }, + }, +]; diff --git a/config/webpack/development.js b/config/webpack/development.js new file mode 100644 index 00000000000..89d35d93896 --- /dev/null +++ b/config/webpack/development.js @@ -0,0 +1,5 @@ +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; + +const environment = require('./environment'); + +module.exports = environment.toWebpackConfig(); diff --git a/config/webpack/environment.js b/config/webpack/environment.js new file mode 100644 index 00000000000..a79bb43a1ff --- /dev/null +++ b/config/webpack/environment.js @@ -0,0 +1,43 @@ +const { environment } = require('@rails/webpacker'); +const webpack = require('webpack'); + +// custom webpack Plugins +const { VueLoaderPlugin } = require('vue-loader'); +const { StatsWriterPlugin } = require('webpack-stats-plugin'); +const MonacoEditorPlugin = require('monaco-editor-webpack-plugin'); + +const customRules = require('./custom/rules'); + +// plugin initialization +environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin()); +environment.loaders = customRules; // webpacker use 'loaders' as key for 'rules' + +environment.plugins.append('StatsWriterPlugin', new StatsWriterPlugin({ + // manifest filename must match config.webpack.manifest_filename + // webpack-rails only needs assetsByChunkName to function properly + filename: 'manifest.json', + transform: function (data, opts) { + const stats = opts.compiler.getStats().toJson({ + chunkModules: false, + source: false, + chunks: false, + modules: false, + assets: true, + }); + return JSON.stringify(stats, null, 2); + }, + }) +); + +environment.plugins.append('MonacoEditorPlugin', new MonacoEditorPlugin()); + +environment.plugins.append('IgnorePlugin', + // prevent pikaday from including moment.js + new webpack.IgnorePlugin(/moment/, /pikaday/) +); + +// custom GitLab config +const gitlabConfig = require('./gitlab'); +environment.config.merge(gitlabConfig); + +module.exports = environment; diff --git a/config/webpack/gitlab.js b/config/webpack/gitlab.js new file mode 100644 index 00000000000..c23f3da9211 --- /dev/null +++ b/config/webpack/gitlab.js @@ -0,0 +1,68 @@ +const path = require('path'); + +const ROOT_PATH = path.resolve(__dirname, '../..'); +const IS_EE = require('./../helpers/is_ee_env'); + +const alias = { + '~': path.join(ROOT_PATH, 'app/assets/javascripts'), + emojis: path.join(ROOT_PATH, 'fixtures/emojis'), + empty_states: path.join(ROOT_PATH, 'app/views/shared/empty_states'), + icons: path.join(ROOT_PATH, 'app/views/shared/icons'), + images: path.join(ROOT_PATH, 'app/assets/images'), + vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'), + vue$: 'vue/dist/vue.esm.js', + spec: path.join(ROOT_PATH, 'spec/javascripts'), + + // the following resolves files which are different between CE and EE + ee_else_ce: path.join(ROOT_PATH, 'app/assets/javascripts'), +}; + +if (IS_EE) { + Object.assign(alias, { + ee: path.join(ROOT_PATH, 'ee/app/assets/javascripts'), + ee_empty_states: path.join(ROOT_PATH, 'ee/app/views/shared/empty_states'), + ee_icons: path.join(ROOT_PATH, 'ee/app/views/shared/icons'), + ee_images: path.join(ROOT_PATH, 'ee/app/assets/images'), + ee_spec: path.join(ROOT_PATH, 'ee/spec/javascripts'), + ee_else_ce: path.join(ROOT_PATH, 'ee/app/assets/javascripts'), + }); +} + +module.exports = { + // resolve + resolve: { + alias, + }, + + // module + module: { + strictExportPresence: true, + }, + + // optimization + // optimization: { + // runtimeChunk: 'single', + // splitChunks: { + // maxInitialRequests: 4, + // cacheGroups: { + // default: false, + // common: () => ({ + // priority: 20, + // name: 'main', + // chunks: 'initial', + // minChunks: autoEntriesCount * 0.9, + // }), + // vendors: { + // priority: 10, + // chunks: 'async', + // test: /[\\/](node_modules|vendor[\\/]assets[\\/]javascripts)[\\/]/, + // }, + // commons: { + // chunks: 'all', + // minChunks: 2, + // reuseExistingChunk: true, + // }, + // }, + // }, + // }, +}; diff --git a/config/webpack/production.js b/config/webpack/production.js new file mode 100644 index 00000000000..4ac9da35ad0 --- /dev/null +++ b/config/webpack/production.js @@ -0,0 +1,24 @@ +process.env.NODE_ENV = process.env.NODE_ENV || 'production'; + +const environment = require('./environment'); + +const path = require('path'); +const ROOT_PATH = path.resolve(__dirname, '../..'); + +// custom webpack plugins - production only +const CompressionPlugin = require('compression-webpack-plugin'); +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); + +// plugin initialization +environment.plugins.append('CompressionPlugin', new CompressionPlugin()); +environment.plugins.append('BundleAnalyzerPlugin', new BundleAnalyzerPlugin({ + analyzerMode: 'static', + generateStatsFile: true, + openAnalyzer: false, + reportFilename: path.join(ROOT_PATH, 'webpack-report/index.html'), + statsFilename: path.join(ROOT_PATH, 'webpack-report/stats.json'), + }) +); + +// export final webpack configuration +module.exports = environment.toWebpackConfig(); diff --git a/config/webpack/test.js b/config/webpack/test.js new file mode 100644 index 00000000000..c5edff94ad2 --- /dev/null +++ b/config/webpack/test.js @@ -0,0 +1,5 @@ +process.env.NODE_ENV = process.env.NODE_ENV || 'development' + +const environment = require('./environment') + +module.exports = environment.toWebpackConfig() |