UNPKG

dinou

Version:

Dinou is a modern React 19 framework with React Server Components, Server Functions, and streaming SSR.

229 lines (220 loc) 6.52 kB
require("dotenv/config"); const path = require("path"); const fs = require("fs"); const ReactServerWebpackPlugin = require("react-server-dom-webpack/plugin"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const createScopedName = require("../core/createScopedName"); const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); const manifestGeneratorPlugin = require("./plugins/manifest-generator-plugin"); const ServerFunctionsPlugin = require("./plugins/server-functions-plugin"); const webpack = require("webpack"); const { regex } = require("../core/asset-extensions"); const isDevelopment = process.env.NODE_ENV !== "production"; const outputDirectory = isDevelopment ? "public" : "dist3"; function getConfigFileIfExists() { const tsconfigPath = path.resolve(process.cwd(), "tsconfig.json"); const jsconfigPath = path.resolve(process.cwd(), "jsconfig.json"); if (fs.existsSync(tsconfigPath)) return tsconfigPath; if (fs.existsSync(jsconfigPath)) return jsconfigPath; return null; } const configFile = getConfigFileIfExists(); module.exports = { mode: isDevelopment ? "development" : "production", entry: { main: [path.resolve(__dirname, "../core/client-webpack.jsx")].filter( Boolean ), error: [path.resolve(__dirname, "../core/client-error-webpack.jsx")].filter( Boolean ), serverFunctionProxy: path.resolve( __dirname, "../core/server-function-proxy-webpack.js" ), }, output: { path: path.resolve(process.cwd(), outputDirectory), filename: "[name]-[contenthash].js", publicPath: "/", clean: true, }, module: { noParse: [/dist3/, /public/], rules: [ // { // test: /\.(js|jsx|ts|tsx)$/, // include: path.resolve(process.cwd(), "dist3"), // use: "null-loader", // }, { test: /\.[jt]sx?$/, include: path.resolve(process.cwd(), "src"), use: [ { loader: path.resolve( __dirname, "./loaders/server-functions-loader.js" ), }, ], }, { test: /\.(js|jsx|ts|tsx)$/, include: [ path.resolve(process.cwd(), "src"), path.resolve(__dirname, "../core"), ], use: { loader: "babel-loader", options: { presets: [ ["@babel/preset-react", { runtime: "automatic" }], "@babel/preset-typescript", ], plugins: [ "@babel/plugin-transform-modules-commonjs", "@babel/plugin-syntax-import-meta", isDevelopment && require.resolve("react-refresh/babel"), ].filter(Boolean), }, }, exclude: [ /node_modules\/(?!dinou)/, path.resolve(process.cwd(), "dist3"), path.resolve(process.cwd(), "public"), ], }, { test: /\.module\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { defaultExport: true, }, }, { loader: "css-loader", options: { modules: { getLocalIdent: (context, localIdentName, localName) => { return createScopedName(localName, context.resourcePath); }, }, importLoaders: 1, }, }, "postcss-loader", ], }, { test: /\.css$/, exclude: /\.module\.css$/, use: [ MiniCssExtractPlugin.loader, "css-loader", { loader: "postcss-loader", options: { postcssOptions: { config: path.resolve(__dirname, "postcss.config.js"), }, }, }, ], }, { test: regex, type: "asset/resource", generator: { filename: (pathData) => { const resourcePath = pathData.module.resourceResolveData?.path || pathData.module.resource; const base = path.basename( resourcePath, path.extname(resourcePath) ); const scoped = createScopedName(base, resourcePath); return `/assets/${scoped}[ext]`; }, publicPath: "", }, }, ], }, plugins: [ isDevelopment && new ReactRefreshWebpackPlugin({ overlay: false }), new ReactServerWebpackPlugin({ isServer: false }), new CopyWebpackPlugin({ patterns: [ { from: "favicons", to: ".", noErrorOnMissing: true, }, ], }), new MiniCssExtractPlugin({ filename: "[name].css", }), manifestGeneratorPlugin, // Ignore any imports that reference the output folders new webpack.IgnorePlugin({ resourceRegExp: /(dist3|public)/ }), new ServerFunctionsPlugin({ manifest: manifestGeneratorPlugin.manifestData, }), ].filter(Boolean), resolve: { extensions: [".js", ".jsx", ".ts", ".tsx"], modules: ["src", "node_modules"], plugins: configFile ? [ new TsconfigPathsPlugin({ configFile, extensions: [".js", ".jsx", ".ts", ".tsx"], }), ] : [], }, externals: { __SERVER_FUNCTION_PROXY__: "__SERVER_FUNCTION_PROXY__", }, optimization: { splitChunks: { cacheGroups: { styles: { name: "styles", type: "css/mini-extract", chunks: "all", enforce: true, }, }, }, }, watchOptions: { ignored: ["public/", "dist3/"], }, ...(isDevelopment ? { devServer: { port: 3001, hot: true, devMiddleware: { index: false, writeToDisk: true, }, proxy: [ { context: () => true, target: "http://localhost:3000", changeOrigin: true, }, ], }, } : {}), };