diff --git a/package.json b/package.json index d2dd193d1..b2278a638 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "browserslist": [ "defaults" ], + "type": "module", "devDependencies": { "@babel/cli": "^7.25.6", "@babel/core": "^7.25.2", diff --git a/webpack.config.js b/webpack.config.js index 9d8cd9033..52cd8d4e3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,33 +2,40 @@ // // SPDX-License-Identifier: AGPL-3.0-or-later -const webpack = require('webpack'); -const path = require('path'); -const tmp = require('tmp'); +import webpack from 'webpack'; +import path from 'path'; +import tmp from 'tmp'; tmp.setGracefulCleanup(); -const fs = require('fs-extra'); -const glob = require('glob'); -const { execSync } = require('child_process'); -const axios = require('axios'); +import fs from 'fs-extra'; +import { glob } from 'glob'; +import execSync from 'child_process'; +import axios from 'axios'; -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); -const { CleanWebpackPlugin } = require('clean-webpack-plugin'); -const CopyPlugin = require('copy-webpack-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); -const yaml = require('js-yaml'); -const postcssPresetEnv = require('postcss-preset-env'); -const RemovePlugin = require('remove-files-webpack-plugin'); -const RealFaviconPlugin = require('real-favicon-webpack-plugin'); -const crypto = require('crypto'); +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'; +import { WebpackManifestPlugin } from 'webpack-manifest-plugin'; +import { CleanWebpackPlugin } from 'clean-webpack-plugin'; +import CopyPlugin from 'copy-webpack-plugin'; +import TerserPlugin from 'terser-webpack-plugin'; +import yaml from 'js-yaml'; +import postcssPresetEnv from 'postcss-preset-env'; +import RemovePlugin from 'remove-files-webpack-plugin'; +import RealFaviconPlugin from 'real-favicon-webpack-plugin'; +import crypto from 'crypto'; -const webpackVersion = require('webpack/package.json').version.split('.').slice(0, 2).join('.'); -const packageVersion = require('./package.json').version; +// import { version as webpackVersion } from 'webpack/package.json' assert { type: 'json' }; // version.split('.').slice(0, 2).join('.'); +// import { version as packageVersion } from './package.json' assert { type: 'json' }; + +import webpackJson from 'webpack/package.json' assert { type: "json" }; +const webpackVersion = webpackJson.version.split('.').slice(0, 2).join('.'); +import packageJson from './package.json' assert { type: "json" }; +const packageVersion = packageJson.version; + +import faviconJson from './config/favicon.json' assert { type: 'json' }; async function webpackConfig() { - const wellKnownCacheDir = path.resolve(__dirname, '.cache/well-known'); - const assetsDirectory = path.resolve(__dirname, 'assets'); + const wellKnownCacheDir = path.resolve(path.dirname('.cache/well-known')); + const assetsDirectory = path.resolve(path.dirname('assets')); let faviconApiVersion = undefined; if (!fs.existsSync(wellKnownCacheDir)) { @@ -93,7 +100,7 @@ async function webpackConfig() { } }}, { loader: 'resolve-url-loader', options: { sourceMap: true }}, - { loader: 'sass-loader', options: { implementation: require('sass'), sourceMap: true }} + { loader: 'sass-loader', options: { implementation: import('sass'), sourceMap: true }} ] }, { @@ -104,8 +111,8 @@ async function webpackConfig() { }, entry: { - main: [ path.resolve(__dirname, 'frontend/src', 'polyfill.js'), - path.resolve(__dirname, 'frontend/src', 'main.js') + main: [ path.resolve('frontend/src/polyfill.js'), + path.resolve('frontend/src/main.js'), ] }, @@ -118,14 +125,14 @@ async function webpackConfig() { ignoreOrder: false, // Enable to remove warnings about conflicting order }), new WebpackManifestPlugin({ - fileName: path.resolve(__dirname, 'config', 'webpack.yml'), + fileName: path.resolve('config/webpack.yml'), publicPath: `wp-${webpackVersion}`, generate: (seed, files, entrypoints) => Object.keys(entrypoints).reduce((acc, fs) => ({...acc, [fs]: files.filter(file => entrypoints[fs].filter(basename => !(/\.map$/.test(basename))).some(basename => file.path.endsWith(basename))).filter(file => file.isInitial).map(file => file.path)}), {}), serialize: yaml.dump }), new CleanWebpackPlugin({ - cleanOnceBeforeBuildPatterns: [ path.resolve(__dirname, 'static'), - path.resolve(__dirname, 'well-known'), + cleanOnceBeforeBuildPatterns: [ path.resolve('static'), + path.resolve('well-known'), ] }), new webpack.IgnorePlugin({ @@ -136,7 +143,6 @@ async function webpackConfig() { VERSION: JSON.stringify(packageVersion) }), ...(() => { - const faviconJson = require('./config/favicon.json'); const langs = new Set(); function findLangs(json) { if (json && json._i18n) { @@ -174,8 +180,8 @@ async function webpackConfig() { cacheHash.update(JSON.stringify(langJsons)); const cacheFiles = new Set([ - ...(Array.from(langs).map(lang => path.resolve(__dirname, langJsons[lang].masterPicture))), - path.resolve(__dirname, 'config/robots.txt') + ...(Array.from(langs).map(lang => path.resolve(langJsons[lang].masterPicture))), + path.resolve('config/robots.txt'), ]); for (const cacheFile of cacheFiles) { @@ -186,7 +192,7 @@ async function webpackConfig() { let cachedVersion = undefined; - const versionFile = path.resolve(__dirname, '.well-known-cache', `${cacheDigest}.version`); + const versionFile = path.resolve(path.dirname('.well-known-cache'), `${cacheDigest}.version`); try { if (fs.existsSync(versionFile)) { cachedVersion = fs.readFileSync(versionFile, 'utf8'); @@ -203,14 +209,14 @@ async function webpackConfig() { return Array.from(langs).map(lang => { const faviconConfig = { versioning: { param_name: 'v', param_value: versionDigest.substr(0,10) }, ...langJsons[lang] }; - const cacheDirectory = path.resolve(__dirname, '.well-known-cache', `${cacheDigest}-${lang}`); + const cacheDirectory = path.resolve(path.dirname('.well-known-cache'), `${cacheDigest}-${lang}`); if (fs.existsSync(wellKnownCacheDir)) { console.log("Using favicons generated by nix"); return [ new CopyPlugin({ patterns: [ - { from: path.resolve(wellKnownCacheDir, lang), to: path.resolve(__dirname, 'well-known', lang) } + { from: path.resolve(wellKnownCacheDir, lang), to: path.resolve(path.dirname('well-known'), lang) } ] }) ]; @@ -219,7 +225,7 @@ async function webpackConfig() { return [ new CopyPlugin({ patterns: [ - { from: cacheDirectory, to: path.resolve(__dirname, 'well-known', lang) } + { from: cacheDirectory, to: path.resolve(path.dirname('well-known'), lang) } ] }) ]; @@ -231,23 +237,23 @@ async function webpackConfig() { return [ new RealFaviconPlugin({ faviconJson: path.relative(".", tmpobj.name), - outputPath: path.resolve(__dirname, 'well-known', lang), + outputPath: path.resolve(path.dirname('well-known'), lang), inject: false }), new CopyPlugin({ patterns: [ - { from: 'config/robots.txt', to: path.resolve(__dirname, 'well-known', lang, 'robots.txt') }, + { from: 'config/robots.txt', to: path.resolve(path.dirname('well-known'), lang, 'robots.txt') }, ] }), { apply: compiler => compiler.hooks.afterEmit.tap('AfterEmitPlugin', compilation => { - const imgFiles = glob.sync(path.resolve(__dirname, 'well-known', lang, '*.@(png)')); + const imgFiles = glob.sync(path.resolve(path.dirname('well-known'), lang, '*.@(png)')); const imgFilesArgs = Array.from(imgFiles).join(" "); execSync(`exiftool -overwrite_original -all= ${imgFilesArgs}`, { stdio: 'inherit' }); }) }, { apply: compiler => compiler.hooks.afterEmit.tap('AfterEmitPlugin', compilation => { - fs.ensureDirSync(__dirname, '.well-known-cache'); - fs.copySync(path.resolve(__dirname, 'well-known', lang), cacheDirectory); + fs.ensureDirSync(path.dirname('.well-known-cache')); + fs.copySync(path.resolve(path.dirname('well-known'), lang), cacheDirectory); if (!fs.existsSync(versionFile)) { fs.writeFileSync(versionFile, faviconApiVersion, { encoding: 'utf8' }); } @@ -262,7 +268,7 @@ async function webpackConfig() { output: { chunkFilename: '[chunkhash].js', filename: '[chunkhash].js', - path: path.resolve(__dirname, 'static', `wp-${webpackVersion}`), + path: path.resolve(path.dirname('static'), `wp-${webpackVersion}`), publicPath: `/static/res/wp-${webpackVersion}/`, hashFunction: 'shake256', hashDigestLength: 36 @@ -287,7 +293,7 @@ async function webpackConfig() { mode: 'production', - recordsPath: path.join(__dirname, 'records.json'), + recordsPath: path.join(path.resolve('records.json')), performance: { assetFilter: (assetFilename) => !(/\.(map|svg|ttf|eot)$/.test(assetFilename)) @@ -297,4 +303,4 @@ async function webpackConfig() { }; } -module.exports = webpackConfig; +export default webpackConfig;