[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\n    \"@babel/preset-react\",\n    [\n      \"@babel/preset-env\",\n      {\n        \"modules\": false\n      }\n    ]\n  ]\n}\n"
  },
  {
    "path": ".browserslistrc",
    "content": "> 1% # Browser usage over 1%\nLast 2 versions # Or last two versions\nIE 8 # Or IE 8"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n# General settings for whole project\n[*]\nindent_style = space\nindent_size = 4\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n# Format specific overrides\n[*.js]\nindent_style = space\nindent_size = 2"
  },
  {
    "path": ".gitignore",
    "content": "node_modules/\ndist/\ni18n-build/\nstatic/\nrecords.json\nstats.json\n\n"
  },
  {
    "path": ".prettierrc",
    "content": "{}\n\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2016 Juho Vepsäläinen\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# webpack-demo - Webpack demo for \"SurviveJS - Webpack 5\"\n\nSee [SurviveJS - Webpack 5](http://survivejs.com/webpack/introduction/) to learn how/why this configuration works.\n\n## License\n\nMIT.\n"
  },
  {
    "path": "demo.txt",
    "content": "{}\n\n"
  },
  {
    "path": "loaders/demo-loader.js",
    "content": "const loaderUtils = require(\"loader-utils\");\n\nmodule.exports = function (content) {\n  const { name } = this.getOptions();\n  const url = loaderUtils.interpolateName(this, name, { content });\n\n  this.emitFile(url, content);\n\n  const path = `__webpack_public_path__ + ${JSON.stringify(url)};`;\n\n  return `export default ${path}`;\n};\n"
  },
  {
    "path": "loaders/pitch-loader.js",
    "content": "module.exports = function (input) {\n  return input + this.getOptions().text;\n};\nmodule.exports.pitch = function (remaining, preceding, input) {\n  console.log(`Remaining: ${remaining}, preceding: ${preceding}\nInput: ${JSON.stringify(input, null, 2)}\n  `);\n\n  return \"pitched\";\n};\n"
  },
  {
    "path": "messages/en.json",
    "content": "{\n  \"hello\": \"Hello world\"\n}\n"
  },
  {
    "path": "messages/fi.json",
    "content": "{\n  \"hello\": \"Terve maailma\"\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"webpack-demo\",\n    \"version\": \"3.0.15\",\n    \"description\": \"\",\n    \"main\": \"index.js\",\n    \"scripts\": {\n        \"deploy\": \"gh-pages -d dist\",\n        \"build:i18n\": \"wp --config webpack.i18n.js\",\n        \"build:ssr\": \"wp --config webpack.ssr.js\",\n        \"build:multi\": \"wp --config webpack.multi.js\",\n        \"build:stats\": \"wp --mode production --json > stats.json\",\n        \"build:mf\": \"wp --config webpack.mf.js --mode production\",\n        \"start:mf\": \"wp --config webpack.mf.js --mode development\",\n        \"start\": \"wp --mode development\",\n        \"build\": \"wp --mode production\"\n    },\n    \"keywords\": [],\n    \"author\": \"\",\n    \"license\": \"MIT\",\n    \"devDependencies\": {\n        \"@babel/core\": \"^7.28.0\",\n        \"@babel/preset-env\": \"^7.28.0\",\n        \"@babel/preset-react\": \"^7.27.1\",\n        \"@tailwindcss/postcss\": \"^4.1.11\",\n        \"autoprefixer\": \"^10.4.21\",\n        \"babel-loader\": \"^10.0.0\",\n        \"browser-refresh\": \"^1.7.3\",\n        \"css-loader\": \"^7.1.2\",\n        \"css-minimizer-webpack-plugin\": \"^7.0.2\",\n        \"express\": \"^5.1.0\",\n        \"gh-pages\": \"^6.3.0\",\n        \"git-revision-webpack-plugin\": \"^5.0.0\",\n        \"glob\": \"^11.0.3\",\n        \"loader-runner\": \"^4.3.0\",\n        \"loader-utils\": \"^3.3.1\",\n        \"memfs\": \"^4.17.2\",\n        \"mini-css-extract-plugin\": \"^2.9.2\",\n        \"mini-html-webpack-plugin\": \"^3.1.3\",\n        \"postcss-loader\": \"^8.1.1\",\n        \"prettier\": \"^3.6.2\",\n        \"purgecss-webpack-plugin\": \"^7.0.2\",\n        \"tailwindcss\": \"^4.1.11\",\n        \"terser-webpack-plugin\": \"^5.3.14\",\n        \"webpack\": \"^5.99.9\",\n        \"webpack-merge\": \"^6.0.1\",\n        \"webpack-nano\": \"^1.1.1\",\n        \"webpack-plugin-serve\": \"^1.6.0\"\n    },\n    \"dependencies\": {\n        \"react\": \"^19.1.0\",\n        \"react-dom\": \"^19.1.0\"\n    }\n}\n"
  },
  {
    "path": "plugins/demo-plugin.js",
    "content": "const { sources, Compilation } = require(\"webpack\");\n\nmodule.exports = class DemoPlugin {\n  constructor(options) {\n    this.options = options;\n  }\n  apply(compiler) {\n    const pluginName = \"DemoPlugin\";\n    const { name } = this.options;\n\n    compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {\n      compilation.hooks.processAssets.tap(\n        {\n          name: pluginName,\n          // See lib/Compilation.js in webpack to understand different stages\n          stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,\n        },\n        () => compilation.emitAsset(name, new sources.RawSource(\"hello\", true))\n      );\n    });\n  }\n};\n"
  },
  {
    "path": "plugins/test-entry.js",
    "content": "console.log(\"hello from entry\");"
  },
  {
    "path": "plugins/test.js",
    "content": "const webpack = require(\"webpack\");\nconst { createFsFromVolume, Volume } = require(\"memfs\");\n\n// The compiler helper accepts filenames should be in the output\n// so it's possible to assert the output easily.\nfunction compile(config, filenames = []) {\n  return new Promise((resolve, reject) => {\n    const compiler = webpack(config);\n    compiler.outputFileSystem = createFsFromVolume(new Volume());\n    const memfs = compiler.outputFileSystem;\n\n    compiler.run((err, stats) => {\n      if (err) {\n        return reject(err);\n      }\n\n      // Now only errors are captured from stats.\n      // It's possible to capture more to assert.\n      if (stats.hasErrors()) {\n        return reject(stats.toString(\"errors-only\"));\n      }\n\n      const ret = {};\n      filenames.forEach((filename) => {\n        // The assumption is that webpack outputs behind ./dist.\n        ret[filename] = memfs.readFileSync(`./dist/${filename}`, {\n          encoding: \"utf-8\",\n        });\n      });\n      return resolve(ret);\n    });\n  });\n}\n\nasync function test() {\n  console.log(\n    await compile({\n      entry: \"./test-entry.js\",\n    }),\n    [\"demo\"]\n  );\n}\n\ntest();\n"
  },
  {
    "path": "run-loader.js",
    "content": "const fs = require(\"fs\");\nconst path = require(\"path\");\nconst { runLoaders } = require(\"loader-runner\");\n\nrunLoaders(\n  {\n    resource: \"./demo.txt\",\n    loaders: [\n      {\n        loader: path.resolve(__dirname, \"./loaders/demo-loader\"),\n        options: {\n          name: \"demo.[ext]\",\n        },\n      },\n      path.resolve(__dirname, \"./loaders/pitch-loader\"),\n    ],\n    context: {\n      emitFile: () => {},\n    },\n    readResource: fs.readFile.bind(fs),\n  },\n  (err, result) => (err ? console.error(err) : console.log(result))\n);\n"
  },
  {
    "path": "server.js",
    "content": "const express = require(\"express\");\nconst { renderToString } = require(\"react-dom/server\");\n\nconst SSR = require(\"./static\");\n\nserver(parseInt(process.env.PORT, 10) || 8080);\n\nfunction server(port) {\n  const app = express();\n\n  app.use(express.static(\"static\"));\n  app.get(\"/\", (req, res) =>\n    res.status(200).send(renderMarkup(renderToString(SSR)))\n  );\n\n  app.listen(port, () => process.send && process.send(\"online\"));\n}\n\nfunction renderMarkup(html) {\n  return `<!DOCTYPE html>\n<html>\n  <head>\n    <title>Webpack SSR Demo</title>\n    <meta charset=\"utf-8\" />\n  </head>\n  <body>\n    <div id=\"app\">${html}</div>\n    <script src=\"./index.js\"></script>\n    <script src=\"${process.env.BROWSER_REFRESH_URL}\"></script>\n  </body>\n</html>`;\n}\n"
  },
  {
    "path": "src/bootstrap.js",
    "content": "import(\"./mf\");\n"
  },
  {
    "path": "src/component.js",
    "content": "import \"!demo-loader?name=foo!./main.css\";\n\nexport default (text = HELLO) => {\n  const element = document.createElement(\"h1\");\n  const worker = new Worker(new URL(\"./worker.js\", import.meta.url));\n  const state = { text };\n\n  worker.addEventListener(\"message\", ({ data: { text } }) => {\n    state.text = text;\n    element.innerHTML = text;\n  });\n\n  element.innerHTML = state.text;\n  element.onclick = () => worker.postMessage({ text: state.text });\n\n  return element;\n};\n"
  },
  {
    "path": "src/header.js",
    "content": "import React from \"react\";\nconst Header = () => <h1 className=\"text-xl\">Demo</h1>;\nexport default Header;\n"
  },
  {
    "path": "src/i18n.js",
    "content": "import \"regenerator-runtime/runtime\";\nimport React, { useEffect, useState } from \"react\";\nimport ReactDOM from \"react-dom\";\n\nconst App = () => {\n  const [language, setLanguage] = useState(\"en\");\n  const [hello, setHello] = useState(\"\");\n  const changeLanguage = () => setLanguage(language === \"en\" ? \"fi\" : \"en\");\n\n  useEffect(() => {\n    translate(language, \"hello\").then(setHello).catch(console.error);\n  }, [language]);\n\n  return (\n    <div>\n      <button onClick={changeLanguage}>Change language</button>\n      <div>{hello}</div>\n    </div>\n  );\n};\n\nfunction translate(locale, text) {\n  return getLocaleData(locale).then((messages) => messages[text]);\n}\n\nasync function getLocaleData(locale) {\n  return import(`../messages/${locale}.json`);\n}\n\nconst root = document.createElement(\"div\");\nroot.setAttribute(\"id\", \"app\");\ndocument.body.appendChild(root);\nReactDOM.render(<App />, root);\n"
  },
  {
    "path": "src/index.js",
    "content": "import \"react\";\nimport \"react-dom\";\nimport \"./main.css\";\nimport component from \"./component\";\nimport { bake } from \"./shake\";\n\nbake();\n\ndocument.body.appendChild(component());\n"
  },
  {
    "path": "src/lazy.js",
    "content": "export default \"Hello from lazy\";\n"
  },
  {
    "path": "src/main.css",
    "content": "@tailwind base;\n@tailwind components;\n\n/* Write your utility classes here */\n\n@tailwind utilities;\n\nbody {\n    background: cornsilk;\n    background-image: url(\"./logo.png\");\n    background-repeat: no-repeat;\n    background-position: center;\n}\n"
  },
  {
    "path": "src/mf.js",
    "content": "import ReactDOM from \"react-dom\";\nimport React from \"react\";\nimport \"./main.css\";\nimport Header from \"mf/header\";\n\nfunction App() {\n  const options = [\"Hello world\", \"Hello fed\", \"Hello webpack\"];\n  const [content, setContent] = React.useState(\"Changes on click.\");\n\n  return (\n    <main className=\"max-w-md mx-auto space-y-8\">\n      <Header />\n      <aside>\n        <ul className=\"flex space-x-8\">\n          {options.map((option) => (\n            <li key={option}>\n              <button\n                className=\"rounded bg-blue-500 text-white p-2\"\n                onClick={() => setContent(option)}\n              >\n                {option}\n              </button>\n            </li>\n          ))}\n        </ul>\n      </aside>\n      <article>{content}</article>\n    </main>\n  );\n}\n\nconst container = document.createElement(\"div\");\ndocument.body.appendChild(container);\nReactDOM.render(<App />, container);\n"
  },
  {
    "path": "src/multi.js",
    "content": "const element = document.createElement(\"div\");\nelement.innerHTML = \"hello multi\";\ndocument.body.appendChild(element);\n"
  },
  {
    "path": "src/shake.js",
    "content": "const shake = () => console.log(\"shake\");\nconst bake = () => console.log(\"bake\");\n\nexport { shake, bake };"
  },
  {
    "path": "src/ssr.js",
    "content": "const React = require(\"react\");\nconst ReactDOM = require(\"react-dom\");\n\nconst SSR = <div onClick={() => alert(\"hello\")}>Hello world</div>;\n\n// Render only in the browser, export otherwise\nif (typeof document === \"undefined\") {\n  module.exports = SSR;\n} else {\n  ReactDOM.hydrate(SSR, document.getElementById(\"app\"));\n}\n"
  },
  {
    "path": "src/worker.js",
    "content": "self.onmessage = ({ data: { text } }) => {\n  self.postMessage({ text: text + text });\n};\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "module.exports = {\n  content: [\"./src/**/*.js\"],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n};\n"
  },
  {
    "path": "tests/add.js",
    "content": "module.exports = (a, b) => a + b;\n"
  },
  {
    "path": "tests/add.test.js",
    "content": "const assert = require(\"assert\");\nconst add = require(\"./add\");\n\ndescribe(\"Demo\", () => {\n  it(\"should add correctly\", () => {\n    assert.equal(add(1, 1), 2);\n  });\n});\n"
  },
  {
    "path": "tests/index.js",
    "content": "// Skip execution in Node\nif (module.hot) {\n  const context = require.context(\n    \"mocha-loader!./\", // Process through mocha-loader\n    false, // Skip recursive processing\n    /\\.test.js$/ // Pick only files ending with .test.js\n  );\n\n  // Execute each test suite\n  context.keys().forEach(context);\n}\n"
  },
  {
    "path": "webpack.config.js",
    "content": "const { mode } = require(\"webpack-nano/argv\");\nconst { merge } = require(\"webpack-merge\");\nconst path = require(\"path\");\n\nconst parts = require(\"./webpack.parts\");\n\nconst cssLoaders = [parts.autoprefix(), parts.tailwind()];\n\nconst commonConfig = merge([\n  {\n    resolveLoader: {\n      alias: {\n        \"demo-loader\": path.resolve(__dirname, \"loaders/demo-loader.js\"),\n      },\n    },\n  },\n  {\n    output: {\n      // Tweak this to match your GitHub project name\n      publicPath: \"/\",\n    },\n  },\n  { entry: [\"./src\"] },\n  parts.page({ title: \"Demo\" }),\n  parts.clean(),\n  parts.extractCSS({ loaders: cssLoaders }),\n  parts.loadImages({\n    limit: 15000,\n  }),\n  parts.loadJavaScript(),\n  parts.setFreeVariable(\"HELLO\", \"hello from config\"),\n]);\n\nconst productionConfig = merge([\n  {\n    output: {\n      chunkFilename: \"[name].[contenthash].js\",\n      filename: \"[name].[contenthash].js\",\n      assetModuleFilename: \"[name].[contenthash][ext][query]\",\n    },\n    recordsPath: path.join(__dirname, \"records.json\"),\n  },\n  parts.minifyJavaScript(),\n  parts.minifyCSS({\n    options: {\n      preset: [\"default\"],\n    },\n  }),\n  parts.eliminateUnusedCSS(),\n  parts.generateSourceMaps({ type: \"source-map\" }),\n  {\n    optimization: {\n      splitChunks: {\n        chunks: \"all\",\n      },\n      runtimeChunk: {\n        name: \"runtime\",\n      },\n    },\n  },\n  parts.attachRevision(),\n]);\n\nconst developmentConfig = merge([parts.devServer()]);\n\nconst getConfig = (mode) => {\n  switch (mode) {\n    case \"production\":\n      return merge(commonConfig, productionConfig, { mode });\n    case \"development\":\n      return merge(commonConfig, developmentConfig, { mode });\n    default:\n      throw new Error(`Trying to use an unknown mode, ${mode}`);\n  }\n};\n\nmodule.exports = getConfig(mode);\n"
  },
  {
    "path": "webpack.i18n.js",
    "content": "const path = require(\"path\");\nconst { MiniHtmlWebpackPlugin } = require(\"mini-html-webpack-plugin\");\nconst APP_SOURCE = path.join(__dirname, \"src\");\n\nmodule.exports = {\n  mode: \"production\",\n  entry: { index: path.join(APP_SOURCE, \"i18n.js\") },\n  module: {\n    rules: [\n      {\n        test: /\\.js$/,\n        include: APP_SOURCE,\n        use: \"babel-loader\",\n      },\n    ],\n  },\n  plugins: [new MiniHtmlWebpackPlugin()],\n};\n"
  },
  {
    "path": "webpack.mf.js",
    "content": "const path = require(\"path\");\nconst { component, mode } = require(\"webpack-nano/argv\");\nconst { merge } = require(\"webpack-merge\");\nconst parts = require(\"./webpack.parts\");\n\nconst commonConfig = merge([\n  {\n    output: { publicPath: \"/\" },\n  },\n  parts.loadJavaScript(),\n  parts.loadImages(),\n  parts.page(),\n  parts.extractCSS({ loaders: [parts.tailwind()] }),\n]);\n\nconst configs = {\n  development: merge(\n    { entry: [\"webpack-plugin-serve/client\"] },\n    parts.devServer()\n  ),\n  production: {},\n};\n\nconst shared = {\n  react: { singleton: true },\n  \"react-dom\": { singleton: true },\n};\nconst componentConfigs = {\n  app: merge(\n    {\n      entry: [path.join(__dirname, \"src\", \"bootstrap.js\")],\n    },\n    parts.page(),\n    parts.federateModule({\n      name: \"app\",\n      remotes: { mf: \"mf@/mf.js\" },\n      shared,\n    })\n  ),\n  header: merge(\n    {\n      entry: [path.join(__dirname, \"src\", \"header.js\")],\n    },\n    parts.federateModule({\n      name: \"mf\",\n      filename: \"mf.js\",\n      exposes: { \"./header\": \"./src/header\" },\n      shared,\n    })\n  ),\n};\n\nif (!component) throw new Error(\"Missing component name\");\n\nmodule.exports = merge(\n  commonConfig,\n  configs[mode],\n  { mode },\n  componentConfigs[component]\n);\n"
  },
  {
    "path": "webpack.multi.js",
    "content": "const { merge } = require(\"webpack-merge\");\nconst parts = require(\"./webpack.parts\");\n\nmodule.exports = merge(\n  { mode: \"production\", entry: { app: \"./src/multi.js\" } },\n  parts.page({ title: \"Demo\" }),\n  parts.page({ title: \"Another\", url: \"another\" })\n);\n"
  },
  {
    "path": "webpack.parts.js",
    "content": "const { WebpackPluginServe } = require(\"webpack-plugin-serve\");\nconst MiniCssExtractPlugin = require(\"mini-css-extract-plugin\");\nconst path = require(\"path\");\nconst glob = require(\"glob\");\nconst { PurgeCSSPlugin } = require(\"purgecss-webpack-plugin\");\nconst webpack = require(\"webpack\");\nconst { GitRevisionPlugin } = require(\"git-revision-webpack-plugin\");\nconst TerserPlugin = require(\"terser-webpack-plugin\");\nconst CssMinimizerPlugin = require(\"css-minimizer-webpack-plugin\");\nconst { MiniHtmlWebpackPlugin } = require(\"mini-html-webpack-plugin\");\nconst { ModuleFederationPlugin } = require(\"webpack\").container;\n\nconst ALL_FILES = glob.sync(path.join(__dirname, \"src/*.js\"));\nconst APP_SOURCE = path.join(__dirname, \"src\");\n\nexports.federateModule = ({ name, filename, exposes, remotes, shared }) => ({\n  plugins: [\n    new ModuleFederationPlugin({ name, filename, exposes, remotes, shared }),\n  ],\n});\n\nexports.page = ({ path = \"\", template, title, chunks } = {}) => ({\n  plugins: [\n    new MiniHtmlWebpackPlugin({\n      chunks,\n      filename: `${path && path + \"/\"}index.html`,\n      context: { title },\n      template,\n    }),\n  ],\n});\n\nexports.setFreeVariable = (key, value) => {\n  const env = {};\n  env[key] = JSON.stringify(value);\n\n  return {\n    plugins: [new webpack.DefinePlugin(env)],\n  };\n};\n\nexports.minifyCSS = ({ options }) => ({\n  optimization: {\n    minimizer: [new CssMinimizerPlugin({ minimizerOptions: options })],\n  },\n});\n\nexports.minifyJavaScript = () => ({\n  optimization: {\n    minimizer: [new TerserPlugin()],\n  },\n});\n\nexports.attachRevision = () => ({\n  plugins: [\n    new webpack.BannerPlugin({\n      banner: new GitRevisionPlugin().version(),\n    }),\n  ],\n});\n\nexports.clean = () => ({\n  output: {\n    clean: true,\n  },\n});\n\nexports.loadJavaScript = () => ({\n  module: {\n    rules: [\n      {\n        test: /\\.js$/,\n        include: APP_SOURCE, // Consider extracting as a parameter\n        use: \"babel-loader\",\n      },\n    ],\n  },\n});\n\nexports.eliminateUnusedCSS = () => ({\n  plugins: [\n    new PurgeCSSPlugin({\n      paths: ALL_FILES, // Consider extracting as a parameter\n      extractors: [\n        {\n          extractor: (content) =>\n            content.match(/[^<>\"'`\\s]*[^<>\"'`\\s:]/g) || [],\n          extensions: [\"html\"],\n        },\n      ],\n    }),\n  ],\n});\n\nexports.extractCSS = ({ options = {}, loaders = [] } = {}) => {\n  return {\n    module: {\n      rules: [\n        {\n          test: /\\.css$/,\n          use: [\n            { loader: MiniCssExtractPlugin.loader, options },\n            \"css-loader\",\n          ].concat(loaders),\n          // If you distribute your code as a package and want to\n          // use _Tree Shaking_, then you should mark CSS extraction\n          // to emit side effects. For most use cases, you don't\n          // have to worry about setting flag.\n          sideEffects: true,\n        },\n      ],\n    },\n    plugins: [\n      new MiniCssExtractPlugin({\n        filename: \"[name].[contenthash].css\",\n      }),\n    ],\n  };\n};\n\nexports.devServer = () => ({\n  watch: true,\n  plugins: [\n    new WebpackPluginServe({\n      port: parseInt(process.env.PORT, 10) || 8080,\n      static: \"./dist\", // Expose if output.path changes\n      liveReload: true,\n      waitForBuild: true,\n    }),\n  ],\n});\n\nexports.tailwind = () => ({\n  loader: \"postcss-loader\",\n  options: {\n    postcssOptions: {\n      plugins: [require(\"@tailwindcss/postcss\")()],\n    },\n  },\n});\n\nexports.autoprefix = () => ({\n  loader: \"postcss-loader\",\n  options: {\n    postcssOptions: {\n      plugins: [require(\"autoprefixer\")()],\n    },\n  },\n});\n\nexports.loadImages = ({ limit } = {}) => ({\n  module: {\n    rules: [\n      {\n        test: /\\.(png|jpg)$/,\n        type: \"asset\",\n        parser: {\n          dataUrlCondition: {\n            maxSize: limit,\n          },\n        },\n      },\n    ],\n  },\n});\n\nexports.generateSourceMaps = ({ type }) => ({\n  devtool: type,\n});\n"
  },
  {
    "path": "webpack.ssr.js",
    "content": "const path = require(\"path\");\n\nconst APP_SOURCE = path.join(__dirname, \"src\");\n\nmodule.exports = {\n  mode: \"production\",\n  entry: { index: path.join(APP_SOURCE, \"ssr.js\") },\n  output: {\n    path: path.join(__dirname, \"static\"),\n    filename: \"[name].js\",\n    libraryTarget: \"umd\",\n    globalObject: \"this\",\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.js$/,\n        include: APP_SOURCE,\n        use: \"babel-loader\",\n      },\n    ],\n  },\n};\n"
  }
]