Created
August 12, 2021 03:45
-
-
Save robertvunabandi/036364d4b8f2c6c663ceb51df80765d9 to your computer and use it in GitHub Desktop.
Example webpack config that uses one entry per file (see `clientEntry` function).
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
/** | |
* Copyright 2020 Robert M. Vunabandi. All Rights Reserved. | |
*/ | |
const fs = require("fs") | |
const path = require("path") | |
const nodeExternals = require("webpack-node-externals"); | |
const webpack = require("webpack") | |
const POLYFILL = "@babel/polyfill" | |
const CLIENT_DIR_PATH = "./src/client/pages/" | |
// Common configurations between client and server | |
const alias = {} | |
alias["@client"] = path.resolve(__dirname, "src/client") | |
alias["@components"] = path.resolve(__dirname, "src/client/components") | |
alias["@enums"] = path.resolve(__dirname, "src/enums") | |
alias["@filegen"] = path.resolve(__dirname, "src/filegen") | |
alias["@src"] = path.resolve(__dirname, "src") | |
alias["@entities"] = path.resolve(__dirname, "src/entities") | |
alias["@utils"] = path.resolve(__dirname, "src/utils") | |
const common_config = { | |
mode: process.env.NODE_ENV || "development", | |
devServer: { | |
hot: true, | |
historyApiFallback: true, | |
}, | |
resolve: { | |
extensions: ["*", ".js", ".jsx"], | |
alias, | |
}, | |
watch: true, | |
} | |
function clientEntry() { | |
const EXTENSION = ".jsx" | |
return fs | |
.readdirSync(CLIENT_DIR_PATH) | |
.filter(f => f.endsWith(EXTENSION)) | |
.map(f => f.slice(0, -EXTENSION.length)) | |
.reduce((entry, page) => { | |
entry[page] = [POLYFILL, `./src/client/pages/${page}.jsx`] | |
return entry | |
}, {}) | |
} | |
// Client configurations | |
const client_config = { | |
entry: clientEntry(), | |
output: { | |
path: path.join(__dirname, "public", "js"), | |
publicPath: "/", | |
filename: "[name].bundle.js", | |
}, | |
module: { | |
rules: [ | |
// React / Javascript Files | |
{ | |
test: /\.jsx?$/, | |
exclude: /node_modules/, | |
use: { | |
loader: "babel-loader", | |
options: { | |
presets: [ | |
"@babel/preset-env", | |
"@babel/preset-flow", | |
"@babel/preset-react", | |
], | |
plugins: [ | |
"@babel/plugin-proposal-class-properties" | |
], | |
}, | |
} | |
}, | |
// CSS Files | |
{ | |
test: /\.s?css$/, | |
exclude: /node_modules/, | |
use: [ | |
// creates style nodes from JS strings | |
"style-loader", | |
// translates CSS into CommonJS | |
"css-loader", | |
// compiles Sass to CSS, using Node Sass by default | |
"sass-loader", | |
], | |
}, | |
// Images | |
{ | |
test: /\.(jpg|png|gif|svg|pdf|ico|txt)$/, | |
exclude: /node_modules/, | |
// TODO: need to watch out for images! | |
use: [ | |
{ | |
loader: "file-loader", | |
options: { | |
name: "[hash:16].[ext]", | |
outputPath: "img", | |
publicPath: "public/img", | |
} | |
} | |
], | |
}, | |
], | |
}, | |
plugins: [ | |
new webpack.HotModuleReplacementPlugin(), | |
], | |
} | |
// Server configurations | |
// This blog helped setup this: | |
// https://blog.jakoblind.no/ssr-webpack-bundle/ | |
const server_config = { | |
context: __dirname, | |
// this source map will show where bugs happen if they happen | |
devtool: "source-map", | |
// importing @babel/polyfill first allows this to run | |
// compile async/await functions, See | |
// https://zachgoll.github.io/blog/2018/async-await/ | |
entry: { | |
db_cli: ["@babel/polyfill", "./src/db/cli/main.js"], | |
generator: ["@babel/polyfill", "./src/filegen/main.js"], | |
playground: ["@babel/polyfill", "./src/playground.js"], | |
server: ["@babel/polyfill", "./src/server.js"], | |
}, | |
externals: [nodeExternals()], | |
output: { | |
path: path.join(__dirname, "bin"), | |
publicPath: "/", | |
filename: "[name].build.js", | |
}, | |
module: { | |
rules: [ | |
// Javascript Files | |
{ | |
test: /\.js$/, | |
exclude: /node_modules/, | |
use: { | |
loader: "babel-loader", | |
options: { | |
presets: [ | |
"@babel/preset-env", | |
"@babel/preset-flow", | |
], | |
plugins: [ | |
"@babel/plugin-proposal-class-properties" | |
], | |
}, | |
} | |
}, | |
], | |
}, | |
node: { | |
__filename: true, | |
__dirname: true, | |
}, | |
plugins: [ | |
new webpack.BannerPlugin({ | |
banner: 'require("source-map-support").install();', | |
raw: true, | |
entryOnly: false | |
}), | |
], | |
target: "node", | |
watchOptions: { | |
aggregateTimeout: 500, | |
ignored: [ | |
"**/node_modules/**", | |
/node_modules/, | |
/views/, | |
], | |
}, | |
} | |
module.exports = [ | |
Object.assign({}, common_config, client_config), | |
Object.assign({}, common_config, server_config), | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Running
ls -1AF
on./src/client/pages
: