Commit 73572761 authored by Phil Hughes's avatar Phil Hughes

Merge branch '45532-upgrade-vue-loader' into 'master'

Resolve "Upgrade vue-loader for bug fixes and a simpler webpack config"

Closes #45532

See merge request gitlab-org/gitlab-ce!19052
parents c6f72ac9 442333d9
...@@ -2,6 +2,7 @@ const fs = require('fs'); ...@@ -2,6 +2,7 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const glob = require('glob'); const glob = require('glob');
const webpack = require('webpack'); const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin; const StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin;
const CopyWebpackPlugin = require('copy-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin'); const CompressionPlugin = require('compression-webpack-plugin');
...@@ -12,7 +13,7 @@ const IS_PRODUCTION = process.env.NODE_ENV === 'production'; ...@@ -12,7 +13,7 @@ const IS_PRODUCTION = process.env.NODE_ENV === 'production';
const IS_DEV_SERVER = process.argv.join(' ').indexOf('webpack-dev-server') !== -1; const IS_DEV_SERVER = process.argv.join(' ').indexOf('webpack-dev-server') !== -1;
const DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost'; const DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost';
const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808; const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808;
const DEV_SERVER_LIVERELOAD = process.env.DEV_SERVER_LIVERELOAD !== 'false'; const DEV_SERVER_LIVERELOAD = IS_DEV_SERVER && process.env.DEV_SERVER_LIVERELOAD !== 'false';
const WEBPACK_REPORT = process.env.WEBPACK_REPORT; const WEBPACK_REPORT = process.env.WEBPACK_REPORT;
const NO_COMPRESSION = process.env.NO_COMPRESSION; const NO_COMPRESSION = process.env.NO_COMPRESSION;
...@@ -61,7 +62,7 @@ function generateEntries() { ...@@ -61,7 +62,7 @@ function generateEntries() {
return Object.assign(manualEntries, autoEntries); return Object.assign(manualEntries, autoEntries);
} }
const config = { module.exports = {
mode: IS_PRODUCTION ? 'production' : 'development', mode: IS_PRODUCTION ? 'production' : 'development',
context: path.join(ROOT_PATH, 'app/assets/javascripts'), context: path.join(ROOT_PATH, 'app/assets/javascripts'),
...@@ -76,38 +77,26 @@ const config = { ...@@ -76,38 +77,26 @@ const config = {
globalObject: 'this', // allow HMR and web workers to play nice globalObject: 'this', // allow HMR and web workers to play nice
}, },
optimization: { resolve: {
nodeEnv: false, extensions: ['.js'],
runtimeChunk: 'single', alias: {
splitChunks: { '~': path.join(ROOT_PATH, 'app/assets/javascripts'),
maxInitialRequests: 4, emojis: path.join(ROOT_PATH, 'fixtures/emojis'),
cacheGroups: { empty_states: path.join(ROOT_PATH, 'app/views/shared/empty_states'),
default: false, icons: path.join(ROOT_PATH, 'app/views/shared/icons'),
common: () => ({ images: path.join(ROOT_PATH, 'app/assets/images'),
priority: 20, vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'),
name: 'main', vue$: 'vue/dist/vue.esm.js',
chunks: 'initial', spec: path.join(ROOT_PATH, 'spec/javascripts'),
minChunks: autoEntriesCount * 0.9,
}),
vendors: {
priority: 10,
chunks: 'async',
test: /[\\/](node_modules|vendor[\\/]assets[\\/]javascripts)[\\/]/,
},
commons: {
chunks: 'all',
minChunks: 2,
reuseExistingChunk: true,
},
},
}, },
}, },
module: { module: {
strictExportPresence: true,
rules: [ rules: [
{ {
test: /\.js$/, test: /\.js$/,
exclude: /(node_modules|vendor\/assets)/, exclude: path => /node_modules|vendor[\\/]assets/.test(path) && !/\.vue\.js/.test(path),
loader: 'babel-loader', loader: 'babel-loader',
options: { options: {
cacheDirectory: path.join(ROOT_PATH, 'tmp/cache/babel-loader'), cacheDirectory: path.join(ROOT_PATH, 'tmp/cache/babel-loader'),
...@@ -147,10 +136,9 @@ const config = { ...@@ -147,10 +136,9 @@ const config = {
}, },
}, },
{ {
test: /katex.min.css$/, test: /.css$/,
include: /node_modules\/katex\/dist/,
use: [ use: [
{ loader: 'style-loader' }, 'vue-style-loader',
{ {
loader: 'css-loader', loader: 'css-loader',
options: { options: {
...@@ -175,9 +163,34 @@ const config = { ...@@ -175,9 +163,34 @@ const config = {
], ],
}, },
], ],
noParse: [/monaco-editor\/\w+\/vs\//], noParse: [/monaco-editor\/\w+\/vs\//],
strictExportPresence: true, },
optimization: {
nodeEnv: false,
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,
},
},
},
}, },
plugins: [ plugins: [
...@@ -197,6 +210,9 @@ const config = { ...@@ -197,6 +210,9 @@ const config = {
}, },
}), }),
// enable vue-loader to use existing loader rules for other module types
new VueLoaderPlugin(),
// prevent pikaday from including moment.js // prevent pikaday from including moment.js
new webpack.IgnorePlugin(/moment/, /pikaday/), new webpack.IgnorePlugin(/moment/, /pikaday/),
...@@ -228,49 +244,13 @@ const config = { ...@@ -228,49 +244,13 @@ const config = {
}, },
}, },
]), ]),
],
resolve: {
extensions: ['.js'],
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'),
},
},
// sqljs requires fs
node: {
fs: 'empty',
},
};
if (IS_PRODUCTION) {
config.devtool = 'source-map';
// compression can require a lot of compute time and is disabled in CI // compression can require a lot of compute time and is disabled in CI
if (!NO_COMPRESSION) { IS_PRODUCTION && !NO_COMPRESSION && new CompressionPlugin(),
config.plugins.push(new CompressionPlugin());
}
}
if (IS_DEV_SERVER) { // WatchForChangesPlugin
config.devtool = 'cheap-module-eval-source-map'; // TODO: publish this as a separate plugin
config.devServer = { IS_DEV_SERVER && {
host: DEV_SERVER_HOST,
port: DEV_SERVER_PORT,
disableHostCheck: true,
headers: { 'Access-Control-Allow-Origin': '*' },
stats: 'errors-only',
hot: DEV_SERVER_LIVERELOAD,
inline: DEV_SERVER_LIVERELOAD,
};
config.plugins.push({
apply(compiler) { apply(compiler) {
compiler.hooks.emit.tapAsync('WatchForChangesPlugin', (compilation, callback) => { compiler.hooks.emit.tapAsync('WatchForChangesPlugin', (compilation, callback) => {
const missingDeps = Array.from(compilation.missingDependencies); const missingDeps = Array.from(compilation.missingDependencies);
...@@ -293,22 +273,34 @@ if (IS_DEV_SERVER) { ...@@ -293,22 +273,34 @@ if (IS_DEV_SERVER) {
callback(); callback();
}); });
}, },
}); },
if (DEV_SERVER_LIVERELOAD) {
config.plugins.push(new webpack.HotModuleReplacementPlugin()); // enable HMR only in webpack-dev-server
} DEV_SERVER_LIVERELOAD && new webpack.HotModuleReplacementPlugin(),
}
if (WEBPACK_REPORT) { // optionally generate webpack bundle analysis
config.plugins.push( WEBPACK_REPORT &&
new BundleAnalyzerPlugin({ new BundleAnalyzerPlugin({
analyzerMode: 'static', analyzerMode: 'static',
generateStatsFile: true, generateStatsFile: true,
openAnalyzer: false, openAnalyzer: false,
reportFilename: path.join(ROOT_PATH, 'webpack-report/index.html'), reportFilename: path.join(ROOT_PATH, 'webpack-report/index.html'),
statsFilename: path.join(ROOT_PATH, 'webpack-report/stats.json'), statsFilename: path.join(ROOT_PATH, 'webpack-report/stats.json'),
}) }),
); ].filter(Boolean),
}
devServer: {
host: DEV_SERVER_HOST,
port: DEV_SERVER_PORT,
disableHostCheck: true,
headers: { 'Access-Control-Allow-Origin': '*' },
stats: 'errors-only',
hot: DEV_SERVER_LIVERELOAD,
inline: DEV_SERVER_LIVERELOAD,
},
module.exports = config; devtool: IS_PRODUCTION ? 'source-map' : 'cheap-module-eval-source-map',
// sqljs requires fs
node: { fs: 'empty' },
};
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment