aboutsummaryrefslogtreecommitdiffstats
path: root/webpack.common.js
diff options
context:
space:
mode:
Diffstat (limited to 'webpack.common.js')
-rw-r--r--webpack.common.js166
1 files changed, 147 insertions, 19 deletions
diff --git a/webpack.common.js b/webpack.common.js
index c8bcb740236..80b0e0838e7 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -1,10 +1,25 @@
+/* eslint-disable n/no-extraneous-require */
/* eslint-disable camelcase */
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
const { VueLoaderPlugin } = require('vue-loader')
+const { readFileSync } = require('fs')
const path = require('path')
+
const BabelLoaderExcludeNodeModulesExcept = require('babel-loader-exclude-node-modules-except')
-const ESLintPlugin = require('eslint-webpack-plugin')
const webpack = require('webpack')
+const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
+const WorkboxPlugin = require('workbox-webpack-plugin')
+const WebpackSPDXPlugin = require('./build/WebpackSPDXPlugin.js')
+
const modules = require('./webpack.modules.js')
+const { codecovWebpackPlugin } = require('@codecov/webpack-plugin')
+
+const appVersion = readFileSync('./version.php').toString().match(/OC_Version.+\[([0-9]{2})/)?.[1] ?? 'unknown'
+const isDev = process.env.NODE_ENV === 'development'
+const isTesting = process.env.TESTING === "true"
const formatOutputFromModules = (modules) => {
// merge all configs into one object, and use AppID to generate the fileNames
@@ -24,7 +39,7 @@ const formatOutputFromModules = (modules) => {
}
const modulesToBuild = () => {
- const MODULE = process.env.MODULE
+ const MODULE = process?.env?.MODULE
if (MODULE) {
if (!modules[MODULE]) {
throw new Error(`No module "${MODULE}" found`)
@@ -37,7 +52,7 @@ const modulesToBuild = () => {
return formatOutputFromModules(modules)
}
-module.exports = {
+const config = {
entry: modulesToBuild(),
output: {
// Step away from the src folder and extract to the js folder
@@ -50,11 +65,13 @@ module.exports = {
// leak local paths https://github.com/webpack/webpack/issues/3603
devtoolNamespace: 'nextcloud',
devtoolModuleFilenameTemplate(info) {
- const rootDir = process.cwd()
+ const rootDir = process?.cwd()
const rel = path.relative(rootDir, info.absoluteResourcePath)
return `webpack:///nextcloud/${rel}`
},
- clean: true,
+ clean: {
+ keep: /icons\.css/, // Keep static icons css
+ },
},
module: {
@@ -84,6 +101,20 @@ module.exports = {
]),
},
{
+ test: /\.tsx?$/,
+ use: [
+ 'babel-loader',
+ {
+ // Fix TypeScript syntax errors in Vue
+ loader: 'ts-loader',
+ options: {
+ transpileOnly: true,
+ },
+ },
+ ],
+ exclude: BabelLoaderExcludeNodeModulesExcept([]),
+ },
+ {
test: /\.js$/,
loader: 'babel-loader',
// automatically detect necessary packages to
@@ -91,7 +122,6 @@ module.exports = {
exclude: BabelLoaderExcludeNodeModulesExcept([
'@nextcloud/dialogs',
'@nextcloud/event-bus',
- '@nextcloud/vue-dashboard',
'davclient.js',
'nextcloud-vue-collections',
'p-finally',
@@ -115,18 +145,21 @@ module.exports = {
test: /\.handlebars/,
loader: 'handlebars-loader',
},
-
+ {
+ resourceQuery: /raw/,
+ type: 'asset/source',
+ },
],
},
optimization: {
splitChunks: {
automaticNameDelimiter: '-',
+ minChunks: 3, // minimum number of chunks that must share the module
cacheGroups: {
vendors: {
// split every dependency into one bundle
test: /[\\/]node_modules[\\/]/,
- enforce: true,
// necessary to keep this name to properly inject it
// see OC_Template.php
name: 'core-common',
@@ -138,27 +171,122 @@ module.exports = {
plugins: [
new VueLoaderPlugin(),
- new ESLintPlugin(),
+ new NodePolyfillPlugin({
+ additionalAliases: ['process'],
+ }),
new webpack.ProvidePlugin({
// Provide jQuery to jquery plugins as some are loaded before $ is exposed globally.
- jQuery: 'jquery',
- // Shim ICAL to prevent using the global object (window.ICAL).
- // The library ical.js heavily depends on instanceof checks which will
- // break if two separate versions of the library are used (e.g. bundled one
- // and global one).
- ICAL: 'ical.js',
+ // We need to provide the path to node_moduels as otherwise npm link will fail due
+ // to tribute.js checking for jQuery in @nextcloud/vue
+ jQuery: path.resolve(path.join(__dirname, 'node_modules/jquery')),
+ }),
+
+ new WorkboxPlugin.GenerateSW({
+ swDest: 'preview-service-worker.js',
+ clientsClaim: true,
+ skipWaiting: true,
+ exclude: [/.*/], // don't do pre-caching
+ inlineWorkboxRuntime: true,
+ sourcemap: false,
+
+ // Increase perfs with less logging
+ disableDevLogs: true,
+
+ // Define runtime caching rules.
+ runtimeCaching: [{
+ // Match any preview file request
+ // /apps/files_trashbin/preview?fileId=156380&a=1
+ // /core/preview?fileId=155842&a=1
+ urlPattern: /^.*\/(apps|core)(\/[a-z-_]+)?\/preview.*/i,
+
+ // Apply a strategy.
+ handler: 'CacheFirst',
+
+ options: {
+ // Use a custom cache name.
+ cacheName: 'previews',
+
+ // Only cache 10000 images.
+ expiration: {
+ maxAgeSeconds: 3600 * 24 * 7, // one week
+ maxEntries: 10000,
+ },
+ },
+ }],
+ }),
+
+ // Make appName & appVersion available as a constants for '@nextcloud/vue' components
+ new webpack.DefinePlugin({ appName: JSON.stringify('Nextcloud') }),
+ new webpack.DefinePlugin({ appVersion: JSON.stringify(appVersion) }),
+
+ // @nextcloud/moment since v1.3.0 uses `moment/min/moment-with-locales.js`
+ // Which works only in Node.js and is not compatible with Webpack bundling
+ // It has an unused function `localLocale` that requires locales by invalid relative path `./locale`
+ // Though it is not used, Webpack tries to resolve it with `require.context` and fails
+ new webpack.IgnorePlugin({
+ resourceRegExp: /^\.\/locale$/,
+ contextRegExp: /moment\/min$/,
+ }),
+ codecovWebpackPlugin({
+ enableBundleAnalysis: !isDev && !isTesting,
+ bundleName: 'nextcloud',
+ telemetry: false,
}),
],
+ externals: {
+ OC: 'OC',
+ OCA: 'OCA',
+ OCP: 'OCP',
+ },
resolve: {
alias: {
// make sure to use the handlebar runtime when importing
handlebars: 'handlebars/runtime',
+ vue$: path.resolve('./node_modules/vue'),
},
- extensions: ['*', '.js', '.vue'],
- symlinks: false,
+ extensions: ['*', '.ts', '.js', '.vue'],
+ extensionAlias: {
+ /**
+ * Resolve TypeScript files when using fully-specified esm import paths
+ * https://github.com/webpack/webpack/issues/13252
+ */
+ '.js': ['.js', '.ts'],
+ },
+ symlinks: true,
fallback: {
- stream: require.resolve('stream-browserify'),
- buffer: require.resolve('buffer'),
+ fs: false,
},
},
}
+
+// Generate reuse license files if not in development mode
+if (!isDev) {
+ config.plugins.push(new WebpackSPDXPlugin({
+ override: {
+ select2: 'MIT',
+ '@nextcloud/axios': 'GPL-3.0-or-later',
+ '@nextcloud/vue': 'AGPL-3.0-or-later',
+ 'nextcloud-vue-collections': 'AGPL-3.0-or-later',
+ },
+ }))
+
+ config.optimization.minimizer = [{
+ apply: (compiler) => {
+ // Lazy load the Terser plugin
+ const TerserPlugin = require('terser-webpack-plugin')
+ new TerserPlugin({
+ extractComments: false,
+ terserOptions: {
+ format: {
+ comments: false,
+ },
+ compress: {
+ passes: 2,
+ },
+ },
+ }).apply(compiler)
+ },
+ }]
+}
+
+module.exports = config