-
-
Save Khauri/59125177c32b1024e9385fc00bda11d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('dotenv').config(); | |
const path = require('path'); | |
const webpack = require('webpack'); | |
const {CleanWebpackPlugin} = require('clean-webpack-plugin'); | |
const MarkoPlugin = require('@marko/webpack/plugin').default; | |
const CSSExtractPlugin = require('mini-css-extract-plugin'); | |
const nodeExternals = require('webpack-node-externals'); | |
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); | |
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); | |
const merge = require('webpack-merge'); | |
const SpawnServerPlugin = require('spawn-server-webpack-plugin') | |
// Constants | |
const {NODE_ENV, BUNDLE_ANALYZER_MODE, PORT} = process.env; | |
const IS_PRODUCTION = /production/.test(NODE_ENV); | |
const IS_DEVELOPMENT = !IS_PRODUCTION; | |
// Plugins | |
const markoPlugin = new MarkoPlugin(); | |
const spawnedServer = new SpawnServerPlugin({args: ['--experimental-worker', '--use-strict']}); | |
const smp = new SpeedMeasurePlugin({disable: true, outputTarget: './smp.txt'}); | |
// Common config (this is a function so that plugins return unique instances) | |
const commonConfig = () => ({ | |
stats: 'minimal', | |
optimization: { | |
nodeEnv: false, | |
noEmitOnErrors: true, | |
}, | |
mode: IS_PRODUCTION ? 'production' : 'development', | |
devtool: IS_PRODUCTION ? 'cheap-module-source-map' : 'inline-cheap-module-source-map', | |
// Configuration for the dev server | |
devServer: IS_DEVELOPMENT ? { | |
stats: 'minimal', | |
...spawnedServer.devServerConfig, | |
} : undefined, | |
output: {publicPath: '/static/'}, | |
resolve: { | |
extensions: ['.js', '.json', '.marko'], | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.marko$/, | |
loader: '@marko/webpack/loader', | |
}, | |
{ | |
test: /\.svg$/, | |
loader: 'svg-url-loader', | |
}, | |
// if a config doesn't have a css loader this willl hopefully output it as a client file when required | |
{ | |
test: /\.(jpe?g|gif|png|eot|woff2?|ttf|s?css)$/, | |
loader: 'file-loader', | |
options: { | |
// File assets from server & browser compiler output to client folder. | |
outputPath: '../client', | |
publicPath: '/static/', | |
}, | |
}, | |
], | |
}, | |
plugins: [ | |
IS_PRODUCTION && new CleanWebpackPlugin(), | |
new webpack.ProvidePlugin({ | |
$: 'jquery', | |
jQuery: 'jquery', | |
}), | |
BUNDLE_ANALYZER_MODE && new BundleAnalyzerPlugin({analyzerMode: BUNDLE_ANALYZER_MODE}), | |
].filter(Boolean), | |
}); | |
const clientConfig = { | |
name: 'Client', | |
optimization: { | |
// This configuration optimizes our common bundles | |
splitChunks: { | |
chunks: 'all', | |
maxSize: 300000, | |
}, | |
}, | |
module: { | |
rules: [ | |
// css on the client is compiled | |
{ | |
test: /\.s?css$/, | |
use: [ | |
CSSExtractPlugin.loader, | |
'css-loader', | |
'postcss-loader', | |
'sass-loader', | |
], | |
}, | |
] | |
}, | |
// Determines the location of the client output | |
output: { | |
filename: `[name]${IS_PRODUCTION ? '[chunkhash:8]' : ''}.js`, | |
path: path.join(__dirname, 'dist/client'), | |
}, | |
plugins: [ | |
IS_DEVELOPMENT && new webpack.HotModuleReplacementPlugin(), | |
new webpack.DefinePlugin({'process.browser': true}), | |
new CSSExtractPlugin({filename: `[name]${IS_PRODUCTION ? '[chunkhash:8]' : ''}.css`}), | |
markoPlugin.browser, | |
].filter(Boolean), | |
}; | |
const serverConfig = { | |
name: 'Server', | |
entry: './index.js', | |
target: 'async-node', | |
optimization: {minimize: false}, | |
output: { | |
libraryTarget: 'commonjs2', | |
path: path.join(__dirname, 'dist/server'), | |
}, | |
externals: [ | |
nodeExternals({allowlist: [/\.(?!(?:jsx?|json)$).{1,5}$/i]}), | |
], | |
plugins: [ | |
new webpack.DefinePlugin({ | |
'process.browser': undefined, | |
'process.env.BUNDLE': true, | |
}), | |
new webpack.BannerPlugin({ | |
entryOnly: true, | |
banner: 'require(\'source-map-support\').install();', | |
include: /\.js$/, | |
raw: true, | |
}), | |
IS_DEVELOPMENT && spawnedServer, | |
markoPlugin.server, | |
].filter(Boolean), | |
}; | |
module.exports = smp.wrap([clientConfig, serverConfig].map(config => merge(commonConfig(), config))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This config is based on https://github.com/marko-js-samples/marko-webpack/blob/master/webpack.config.js with a few changes.
I have a server entrypoint at
index.js
, and when css files are required on the server it generates amain.css
file in thedist/server
folder, which gets listed as an output file for the main entrypoint, causing spawn-server to try and run it, which throws an error. To solve this I just used the file-loader instead of the css-loaders on the server and let the css get placed indist/client
.