Delete Webpack See merge request soapbox-pub/soapbox!2667environments/review-develop-3zknud/deployments/3796
commit
ec9eae8174
@ -1,22 +0,0 @@
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
import type { Configuration } from 'webpack';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const { NODE_ENV } = process.env;
|
||||
|
||||
let configuration: Configuration = {};
|
||||
|
||||
switch (NODE_ENV) {
|
||||
case 'development':
|
||||
case 'production':
|
||||
case 'test':
|
||||
configuration = require(`./webpack/${NODE_ENV}`).default;
|
||||
break;
|
||||
default:
|
||||
console.error('ERROR: NODE_ENV must be set to either `development`, `test`, or `production`.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
export default configuration;
|
@ -1,32 +0,0 @@
|
||||
import { join } from 'path';
|
||||
import { env } from 'process';
|
||||
|
||||
const {
|
||||
FE_SUBDIRECTORY,
|
||||
FE_BUILD_DIR,
|
||||
} = require(join(__dirname, '..', 'app', 'soapbox', 'build-config'));
|
||||
|
||||
const settings = {
|
||||
source_path: 'app',
|
||||
public_root_path: FE_BUILD_DIR,
|
||||
test_root_path: `${FE_BUILD_DIR}-test`,
|
||||
cache_path: 'tmp/cache',
|
||||
resolved_paths: [],
|
||||
extensions: [ '.js', '.jsx', '.cjs', '.mjs', '.ts', '.tsx', '.sass', '.scss', '.css', '.module.sass', '.module.scss', '.module.css', '.png', '.svg', '.gif', '.jpeg', '.jpg' ],
|
||||
};
|
||||
|
||||
const outputDir = env.NODE_ENV === 'test' ? settings.test_root_path : settings.public_root_path;
|
||||
|
||||
const output = {
|
||||
path: join(__dirname, '..', outputDir, FE_SUBDIRECTORY),
|
||||
};
|
||||
|
||||
const exportEnv = {
|
||||
NODE_ENV: env.NODE_ENV,
|
||||
};
|
||||
|
||||
export {
|
||||
settings,
|
||||
exportEnv as env,
|
||||
output,
|
||||
};
|
@ -1,127 +0,0 @@
|
||||
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
||||
console.log('Running in development mode'); // eslint-disable-line no-console
|
||||
|
||||
import { join } from 'path';
|
||||
|
||||
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
|
||||
import { merge } from 'webpack-merge';
|
||||
|
||||
import sharedConfig from './shared';
|
||||
|
||||
import type { Configuration } from 'webpack';
|
||||
import type { Configuration as DevServerConfiguration, ProxyConfigMap } from 'webpack-dev-server';
|
||||
|
||||
const watchOptions: Configuration['watchOptions'] = {};
|
||||
|
||||
const {
|
||||
DEVSERVER_URL,
|
||||
BACKEND_URL,
|
||||
PATRON_URL,
|
||||
PROXY_HTTPS_INSECURE,
|
||||
} = process.env;
|
||||
|
||||
const DEFAULTS = {
|
||||
DEVSERVER_URL: 'http://localhost:3036',
|
||||
PATRON_URL: 'http://localhost:3037',
|
||||
};
|
||||
|
||||
const { FE_SUBDIRECTORY } = require(join(__dirname, '..', 'app', 'soapbox', 'build-config'));
|
||||
|
||||
const backendEndpoints = [
|
||||
'/api',
|
||||
'/pleroma',
|
||||
'/nodeinfo',
|
||||
'/socket',
|
||||
'/oauth',
|
||||
'/.well-known/webfinger',
|
||||
'/static',
|
||||
'/main/ostatus',
|
||||
'/ostatus_subscribe',
|
||||
'/favicon.png',
|
||||
];
|
||||
|
||||
const makeProxyConfig = (): ProxyConfigMap => {
|
||||
const secureProxy = PROXY_HTTPS_INSECURE !== 'true';
|
||||
|
||||
const proxyConfig: ProxyConfigMap = {};
|
||||
proxyConfig['/api/patron'] = {
|
||||
target: PATRON_URL || DEFAULTS.PATRON_URL,
|
||||
secure: secureProxy,
|
||||
changeOrigin: true,
|
||||
};
|
||||
backendEndpoints.map(endpoint => {
|
||||
proxyConfig[endpoint] = {
|
||||
target: BACKEND_URL,
|
||||
secure: secureProxy,
|
||||
changeOrigin: true,
|
||||
};
|
||||
});
|
||||
return proxyConfig;
|
||||
};
|
||||
|
||||
if (process.env.VAGRANT) {
|
||||
// If we are in Vagrant, we can't rely on inotify to update us with changed
|
||||
// files, so we must poll instead. Here, we poll every second to see if
|
||||
// anything has changed.
|
||||
watchOptions.poll = 1000;
|
||||
}
|
||||
|
||||
const devServerUrl = (() => {
|
||||
try {
|
||||
return new URL(DEVSERVER_URL || DEFAULTS.DEVSERVER_URL);
|
||||
} catch {
|
||||
return new URL(DEFAULTS.DEVSERVER_URL);
|
||||
}
|
||||
})();
|
||||
|
||||
const devServer: DevServerConfiguration = {
|
||||
compress: true,
|
||||
host: devServerUrl.hostname,
|
||||
port: devServerUrl.port,
|
||||
https: devServerUrl.protocol === 'https:',
|
||||
hot: true,
|
||||
allowedHosts: 'all',
|
||||
historyApiFallback: {
|
||||
disableDotRule: true,
|
||||
index: join(FE_SUBDIRECTORY, '/'),
|
||||
},
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
client: {
|
||||
overlay: true,
|
||||
},
|
||||
static: {
|
||||
serveIndex: true,
|
||||
},
|
||||
proxy: makeProxyConfig(),
|
||||
};
|
||||
|
||||
const configuration: Configuration = {
|
||||
mode: 'development',
|
||||
cache: true,
|
||||
devtool: 'source-map',
|
||||
|
||||
stats: {
|
||||
preset: 'errors-warnings',
|
||||
errorDetails: true,
|
||||
},
|
||||
|
||||
output: {
|
||||
pathinfo: true,
|
||||
},
|
||||
|
||||
watchOptions: Object.assign(
|
||||
{},
|
||||
{ ignored: '**/node_modules/**' },
|
||||
watchOptions,
|
||||
),
|
||||
|
||||
plugins: [
|
||||
new ReactRefreshWebpackPlugin(),
|
||||
],
|
||||
|
||||
devServer,
|
||||
};
|
||||
|
||||
export default merge<Configuration>(sharedConfig, configuration);
|
@ -1,14 +0,0 @@
|
||||
import { resolve } from 'path';
|
||||
|
||||
import type { LoaderContext } from 'webpack';
|
||||
|
||||
/**
|
||||
* Forces recompile whenever the current commit changes.
|
||||
* Useful for generating the version hash in the UI.
|
||||
*/
|
||||
function loader(this: LoaderContext<{}>, content: string) {
|
||||
this.addDependency(resolve(__dirname, '../../.git/logs/HEAD'));
|
||||
this.callback(undefined, content);
|
||||
}
|
||||
|
||||
export default loader;
|
@ -1,154 +0,0 @@
|
||||
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
||||
console.log('Running in production mode'); // eslint-disable-line no-console
|
||||
|
||||
import { join } from 'path';
|
||||
|
||||
// @ts-ignore: No types available.
|
||||
import OfflinePlugin from '@lcdp/offline-plugin';
|
||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||
import { merge } from 'webpack-merge';
|
||||
|
||||
import sharedConfig from './shared';
|
||||
|
||||
import type { Configuration } from 'webpack';
|
||||
|
||||
const { FE_SUBDIRECTORY } = require(join(__dirname, '..', 'app', 'soapbox', 'build-config'));
|
||||
const joinPublicPath = (...paths: string[]) => join(FE_SUBDIRECTORY, ...paths);
|
||||
|
||||
const configuration: Configuration = {
|
||||
mode: 'production',
|
||||
devtool: 'source-map',
|
||||
stats: 'errors-warnings',
|
||||
bail: true,
|
||||
|
||||
output: {
|
||||
filename: 'packs/js/[name]-[chunkhash].js',
|
||||
chunkFilename: 'packs/js/[name]-[chunkhash].chunk.js',
|
||||
hotUpdateChunkFilename: 'packs/js/[id]-[contenthash].hot-update.js',
|
||||
},
|
||||
|
||||
optimization: {
|
||||
minimize: true,
|
||||
},
|
||||
|
||||
plugins: [
|
||||
// Generates report.html
|
||||
new BundleAnalyzerPlugin({
|
||||
analyzerMode: 'static',
|
||||
openAnalyzer: false,
|
||||
logLevel: 'silent',
|
||||
}),
|
||||
new OfflinePlugin({
|
||||
autoUpdate: true,
|
||||
responseStrategy: 'network-first',
|
||||
caches: {
|
||||
main: [':rest:'],
|
||||
additional: [
|
||||
':externals:',
|
||||
'packs/images/32-*.png', // used in emoji-mart
|
||||
'packs/icons/*.svg',
|
||||
],
|
||||
optional: [
|
||||
'**/locale_*.js', // don't fetch every locale; the user only needs one
|
||||
'**/*.chunk.js', // only cache chunks when needed
|
||||
'**/*.chunk.css',
|
||||
'**/*.woff2', // the user may have system-fonts enabled
|
||||
// images can be cached on-demand
|
||||
'**/*.png',
|
||||
'**/*.svg',
|
||||
],
|
||||
},
|
||||
externals: [
|
||||
joinPublicPath('packs/emoji/1f602.svg'), // used for emoji picker dropdown
|
||||
|
||||
// Default emoji reacts
|
||||
joinPublicPath('packs/emoji/1f44d.svg'), // Thumbs up
|
||||
joinPublicPath('packs/emoji/2764.svg'), // Heart
|
||||
joinPublicPath('packs/emoji/1f606.svg'), // Laughing
|
||||
joinPublicPath('packs/emoji/1f62e.svg'), // Surprised
|
||||
joinPublicPath('packs/emoji/1f622.svg'), // Crying
|
||||
joinPublicPath('packs/emoji/1f629.svg'), // Weary
|
||||
joinPublicPath('packs/emoji/1f621.svg'), // Angry (Spinster)
|
||||
],
|
||||
excludes: [
|
||||
'**/*.gz',
|
||||
'**/*.map',
|
||||
'**/*.LICENSE.txt',
|
||||
'stats.json',
|
||||
'report.html',
|
||||
'instance/**/*',
|
||||
// any browser that supports ServiceWorker will support woff2
|
||||
'**/*.eot',
|
||||
'**/*.ttf',
|
||||
'**/*-webfont-*.svg',
|
||||
'**/*.woff',
|
||||
// Sounds return a 206 causing sw.js to crash
|
||||
// https://stackoverflow.com/a/66335638
|
||||
'**/*.ogg',
|
||||
'**/*.oga',
|
||||
'**/*.mp3',
|
||||
'404.html',
|
||||
'assets-manifest.json',
|
||||
// It would be nice to serve these, but they bloat up sw.js
|
||||
'packs/images/crypto/**/*',
|
||||
'packs/emoji/**/*',
|
||||
],
|
||||
ServiceWorker: {
|
||||
cacheName: 'soapbox',
|
||||
entry: join(__dirname, '../app/soapbox/service-worker/entry.ts'),
|
||||
events: true,
|
||||
minify: true,
|
||||
},
|
||||
cacheMaps: [{
|
||||
// NOTE: This function gets stringified by OfflinePlugin, so don't try
|
||||
// moving it anywhere else or making it depend on anything outside it!
|
||||
// https://github.com/NekR/offline-plugin/blob/master/docs/cache-maps.md
|
||||
match: (url: URL) => {
|
||||
const { pathname } = url;
|
||||
|
||||
const backendRoutes = [
|
||||
'/.well-known',
|
||||
'/activities',
|
||||
'/admin',
|
||||
'/api',
|
||||
'/auth',
|
||||
'/inbox',
|
||||
'/instance',
|
||||
'/internal',
|
||||
'/main/ostatus',
|
||||
'/manifest.json',
|
||||
'/media',
|
||||
'/nodeinfo',
|
||||
'/oauth',
|
||||
'/objects',
|
||||
'/ostatus_subscribe',
|
||||
'/pghero',
|
||||
'/phoenix',
|
||||
'/pleroma',
|
||||
'/proxy',
|
||||
'/relay',
|
||||
'/sidekiq',
|
||||
'/socket',
|
||||
'/static',
|
||||
'/unsubscribe',
|
||||
'/images',
|
||||
'/favicon.ico',
|
||||
'/favicon.png',
|
||||
'/apple-touch-icon.png',
|
||||
'/browserconfig.xml',
|
||||
'/robots.txt',
|
||||
'/report.html',
|
||||
];
|
||||
|
||||
if (backendRoutes.some(path => pathname.startsWith(path)) || pathname.endsWith('/embed') || pathname.endsWith('.rss')) {
|
||||
return url;
|
||||
}
|
||||
},
|
||||
requestTypes: ['navigate'],
|
||||
}],
|
||||
safeToUseOptionalCaches: true,
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
export default merge<Configuration>(sharedConfig, configuration);
|
@ -1,80 +0,0 @@
|
||||
// Asset modules
|
||||
// https://webpack.js.org/guides/asset-modules/
|
||||
|
||||
import { resolve } from 'path';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
// These are processed in reverse-order
|
||||
// We use the name 'packs' instead of 'assets' for legacy reasons
|
||||
const rules: RuleSetRule[] = [{
|
||||
test: /\.(png|svg)/,
|
||||
type: 'asset/resource',
|
||||
include: [
|
||||
resolve('app', 'assets', 'images'),
|
||||
resolve('node_modules', 'emoji-datasource'),
|
||||
resolve('node_modules', 'leaflet'),
|
||||
],
|
||||
generator: {
|
||||
filename: 'packs/images/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}, {
|
||||
test: /\.(ttf|eot|svg|woff|woff2)/,
|
||||
type: 'asset/resource',
|
||||
include: [
|
||||
resolve('app', 'assets', 'fonts'),
|
||||
resolve('node_modules', 'fork-awesome'),
|
||||
resolve('node_modules', 'line-awesome'),
|
||||
resolve('node_modules', '@fontsource'),
|
||||
],
|
||||
generator: {
|
||||
filename: 'packs/fonts/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}, {
|
||||
test: /\.(ogg|oga|mp3)/,
|
||||
type: 'asset/resource',
|
||||
include: resolve('app', 'assets', 'sounds'),
|
||||
generator: {
|
||||
filename: 'packs/sounds/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}, {
|
||||
test: /\.svg$/,
|
||||
type: 'asset/resource',
|
||||
include: resolve('node_modules', 'twemoji'),
|
||||
generator: {
|
||||
filename: 'packs/emoji/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}, {
|
||||
test: /\.svg$/,
|
||||
type: 'asset/resource',
|
||||
include: resolve('app', 'assets', 'icons'),
|
||||
generator: {
|
||||
filename: 'packs/icons/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}, {
|
||||
test: /\.svg$/,
|
||||
type: 'asset/resource',
|
||||
include: resolve('node_modules', 'bootstrap-icons'),
|
||||
generator: {
|
||||
filename: 'packs/icons/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}, {
|
||||
test: /\.svg$/,
|
||||
type: 'asset/resource',
|
||||
include: [
|
||||
resolve('node_modules', '@tabler'),
|
||||
resolve('custom', 'modules', '@tabler'),
|
||||
],
|
||||
generator: {
|
||||
filename: 'packs/icons/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}, {
|
||||
test: /\.svg$/,
|
||||
type: 'asset/resource',
|
||||
include: resolve('node_modules', 'cryptocurrency-icons'),
|
||||
generator: {
|
||||
filename: 'packs/images/crypto/[name]-[contenthash:8][ext]',
|
||||
},
|
||||
}];
|
||||
|
||||
export default rules;
|
@ -1,24 +0,0 @@
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { env } from '../configuration';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
// This is a hack, used to force build-config @preval to recompile
|
||||
// https://github.com/kentcdodds/babel-plugin-preval/issues/19
|
||||
|
||||
const rule: RuleSetRule = {
|
||||
test: resolve(__dirname, '../../app/soapbox/build-config.js'),
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: false,
|
||||
cacheCompression: env.NODE_ENV === 'production',
|
||||
compact: env.NODE_ENV === 'production',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default rule;
|
@ -1,24 +0,0 @@
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { env } from '../configuration';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
// This is a hack, used in conjunction with rules/git-refresh.js
|
||||
// https://github.com/kentcdodds/babel-plugin-preval/issues/19
|
||||
|
||||
const rule: RuleSetRule = {
|
||||
test: resolve(__dirname, '../../app/soapbox/utils/code.js'),
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: false,
|
||||
cacheCompression: env.NODE_ENV === 'production',
|
||||
compact: env.NODE_ENV === 'production',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default rule;
|
@ -1,36 +0,0 @@
|
||||
import { join, resolve } from 'path';
|
||||
|
||||
import { env, settings } from '../configuration';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV === 'development';
|
||||
|
||||
const rule: RuleSetRule = {
|
||||
test: /\.(js|jsx|cjs|mjs|ts|tsx)$/,
|
||||
include: [
|
||||
settings.source_path,
|
||||
...settings.resolved_paths,
|
||||
].map(p => resolve(p)),
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
// disable type checker - we will use it in fork plugin
|
||||
transpileOnly: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: join(settings.cache_path, 'babel-loader'),
|
||||
cacheCompression: env.NODE_ENV === 'production',
|
||||
compact: env.NODE_ENV === 'production',
|
||||
plugins: isDevelopment ? ['react-refresh/babel'] : [],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default rule;
|
@ -1,32 +0,0 @@
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
const rule: RuleSetRule = {
|
||||
test: /\.s?css$/i,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
importLoaders: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
implementation: require('sass'),
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default rule;
|
@ -1,13 +0,0 @@
|
||||
import { resolve } from 'path';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
/** Recompile code.js whenever git changes. */
|
||||
const rule: RuleSetRule = {
|
||||
test: resolve(__dirname, '../../app/soapbox/utils/code.js'),
|
||||
use: {
|
||||
loader: resolve(__dirname, '../loaders/git-loader.ts'),
|
||||
},
|
||||
};
|
||||
|
||||
export default rule;
|
@ -1,23 +0,0 @@
|
||||
import assets from './assets';
|
||||
import babel from './babel';
|
||||
import buildConfig from './babel-build-config';
|
||||
import git from './babel-git';
|
||||
import css from './css';
|
||||
import gitRefresh from './git-refresh';
|
||||
import nodeModules from './node-modules';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
// Webpack loaders are processed in reverse order
|
||||
// https://webpack.js.org/concepts/loaders/#loader-features
|
||||
const rules: RuleSetRule[] = [
|
||||
...assets,
|
||||
css,
|
||||
nodeModules,
|
||||
babel,
|
||||
git,
|
||||
gitRefresh,
|
||||
buildConfig,
|
||||
];
|
||||
|
||||
export default rules;
|
@ -1,29 +0,0 @@
|
||||
import { join } from 'path';
|
||||
|
||||
import { env, settings } from '../configuration';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
const rule: RuleSetRule = {
|
||||
test: /\.(js|mjs)$/,
|
||||
include: /node_modules/,
|
||||
exclude: [
|
||||
/@babel(?:\/|\\{1,2})runtime/,
|
||||
/\bcore-js\b/,
|
||||
/\bwebpack\/buildin\b/,
|
||||
],
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
babelrc: false,
|
||||
cacheDirectory: join(settings.cache_path, 'babel-loader-node-modules'),
|
||||
cacheCompression: env.NODE_ENV === 'production',
|
||||
compact: false,
|
||||
sourceMaps: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default rule;
|
@ -1,171 +0,0 @@
|
||||
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
||||
|
||||
import fs from 'fs';
|
||||
import { join, resolve } from 'path';
|
||||
|
||||
import CopyPlugin from 'copy-webpack-plugin';
|
||||
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
||||
import HtmlWebpackHarddiskPlugin from 'html-webpack-harddisk-plugin';
|
||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import webpack, { Configuration } from 'webpack';
|
||||
import AssetsManifestPlugin from 'webpack-assets-manifest';
|
||||
import DeadCodePlugin from 'webpack-deadcode-plugin';
|
||||
|
||||
import { env, settings, output } from './configuration';
|
||||
import rules from './rules';
|
||||
|
||||
const { FE_SUBDIRECTORY, FE_INSTANCE_SOURCE_DIR } = require(join(__dirname, '..', 'app', 'soapbox', 'build-config'));
|
||||
|
||||
/** Return file as string, or return empty string. */
|
||||
const readFile = (filename: string) => {
|
||||
try {
|
||||
return fs.readFileSync(filename, 'utf8');
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const makeHtmlConfig = (params = {}): HtmlWebpackPlugin.Options => {
|
||||
const defaults: HtmlWebpackPlugin.Options = {
|
||||
template: 'app/index.ejs',
|
||||
chunksSortMode: 'manual',
|
||||
chunks: ['common', 'locale_en', 'application', 'styles'],
|
||||
alwaysWriteToDisk: true,
|
||||
minify: {
|
||||
collapseWhitespace: true,
|
||||
removeComments: false,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
useShortDoctype: true,
|
||||
},
|
||||
templateParameters: {
|
||||
snippets: readFile(resolve('custom/snippets.html')),
|
||||
},
|
||||
};
|
||||
|
||||
return Object.assign(defaults, params);
|
||||
};
|
||||
|
||||
const configuration: Configuration = {
|
||||
entry: {
|
||||
application: resolve('app/soapbox/main.tsx'),
|
||||
},
|
||||
|
||||
output: {
|
||||
filename: 'packs/js/[name].js',
|
||||
chunkFilename: 'packs/js/[name].chunk.js',
|
||||
hotUpdateChunkFilename: 'packs/js/[id].hot-update.js',
|
||||
path: output.path,
|
||||
publicPath: FE_SUBDIRECTORY || '/',
|
||||
},
|
||||
|
||||
optimization: {
|
||||
chunkIds: 'total-size',
|
||||
moduleIds: 'size',
|
||||
runtimeChunk: {
|
||||
name: 'common',
|
||||
},
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
default: false,
|
||||
defaultVendors: false,
|
||||
common: {
|
||||
name: 'common',
|
||||
chunks: 'all',
|
||||
minChunks: 2,
|
||||
minSize: 0,
|
||||
test: /^(?!.*[\\\/]node_modules[\\\/]react-intl[\\\/]).+$/,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
module: {
|
||||
rules,
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
}),
|
||||
new ForkTsCheckerWebpackPlugin({ typescript: { memoryLimit: 8192 } }),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'packs/css/[name]-[contenthash:8].css',
|
||||
chunkFilename: 'packs/css/[name]-[contenthash:8].chunk.css',
|
||||
}),
|
||||
// @ts-ignore
|
||||
new AssetsManifestPlugin({
|
||||
integrity: false,
|
||||
entrypoints: true,
|
||||
writeToDisk: true,
|
||||
publicPath: true,
|
||||
}),
|
||||
// https://github.com/MQuy/webpack-deadcode-plugin
|
||||
// @ts-ignore
|
||||
new DeadCodePlugin({
|
||||
patterns: [
|
||||
'app/**/*',
|
||||
],
|
||||
exclude: [
|
||||
'**/*.test.*',
|
||||
'**/__*__/*',
|
||||
'**/(LICENSE|README|COPYING)(.md|.txt)?',
|
||||
// This file is imported with @preval
|
||||
'app/soapbox/features/emoji/emoji-map.json',
|
||||
],
|
||||
}),
|
||||
// https://github.com/jantimon/html-webpack-plugin#options
|
||||
new HtmlWebpackPlugin(makeHtmlConfig()),
|
||||
new HtmlWebpackPlugin(makeHtmlConfig({ filename: '404.html' })),
|
||||
new HtmlWebpackHarddiskPlugin(),
|
||||
new CopyPlugin({
|
||||
patterns: [{
|
||||
from: join(__dirname, '../node_modules/twemoji/assets/svg'),
|
||||
to: join(output.path, 'packs/emoji'),
|
||||
}, {
|
||||
from: join(__dirname, '..', 'app', FE_INSTANCE_SOURCE_DIR),
|
||||
to: join(output.path, 'instance'),
|
||||
}, {
|
||||
from: join(__dirname, '../custom/instance'),
|
||||
to: join(output.path, 'instance'),
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
ignore: ['**/.gitkeep'],
|
||||
},
|
||||
}],
|
||||
options: {
|
||||
concurrency: 100,
|
||||
},
|
||||
}),
|
||||
],
|
||||
|
||||
resolve: {
|
||||
extensions: settings.extensions,
|
||||
modules: [
|
||||
resolve('custom', 'modules'),
|
||||
resolve(settings.source_path),
|
||||
'node_modules',
|
||||
],
|
||||
alias: {
|
||||
'classnames': 'clsx',
|
||||
'icons': resolve('app', 'icons'),
|
||||
'custom': resolve('custom'),
|
||||
},
|
||||
fallback: {
|
||||
path: require.resolve('path-browserify'),
|
||||
util: require.resolve('util'),
|
||||
// https://github.com/facebook/react/issues/20235#issuecomment-1061708958
|
||||
'react/jsx-runtime': 'react/jsx-runtime.js',
|
||||
'react/jsx-dev-runtime': 'react/jsx-dev-runtime.js',
|
||||
},
|
||||
},
|
||||
|
||||
resolveLoader: {
|
||||
modules: ['node_modules'],
|
||||
},
|
||||
};
|
||||
|
||||
export default configuration;
|
@ -1,14 +0,0 @@
|
||||
// Note: You must restart bin/webpack-dev-server for changes to take effect
|
||||
console.log('Running in test mode'); // eslint-disable-line no-console
|
||||
|
||||
import { merge } from 'webpack-merge';
|
||||
|
||||
import sharedConfig from './shared';
|
||||
|
||||
import type { Configuration } from 'webpack';
|
||||
|
||||
const configuration: Configuration = {
|
||||
mode: 'development',
|
||||
};
|
||||
|
||||
export default merge<Configuration>(sharedConfig, configuration);
|
Loading…
Reference in new issue