marko-js / webpack

A loader for marko files and a plugin for universal bundling
MIT License
13 stars 4 forks source link

Loader support for split component lazy hydration #46

Closed mcferrenm closed 3 years ago

mcferrenm commented 3 years ago

Description

As part of the lazy hydration PR in marko/next, we need the loader to handle loading multiple possible instances of marko runtime. (prob not describing this perfectly).

Why

Possible Implementation & Open Questions

In the working version on my local, I believe you added to loader/get-asset-code.js a Set to handle this in the code gen: const writtenAssets = this.global.___written || (this.global.___written = new Set());

Additionally we used the following webpack 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 SpawnServerPlugin = require("spawn-server-webpack-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");

const { NODE_ENV } = process.env;
const isProd = NODE_ENV === "production";
const isDev = !isProd;
const markoPlugin = new MarkoPlugin();
const spawnedServer = isDev && new SpawnServerPlugin();

module.exports = [
  compiler({
    name: "Client",
    optimization: {
      runtimeChunk: "single",
      splitChunks: {
        chunks: "all",
        cacheGroups: {
          vendors: {
            test: /\/(node_modules|marko)\//,
            name: "vendors"
          }
        }
      }
    },
    output: {
      filename: "[name].[contenthash:8].js",
      path: path.join(__dirname, "dist/client")
    },
    devServer: isDev ? {
      overlay: true,
      stats: "minimal",
      contentBase: false,
      ...spawnedServer.devServerConfig
    }: undefined,
    plugins: [
      new webpack.DefinePlugin({
        "process.browser": true
      }),
      new CSSExtractPlugin({
        filename: "[name].[contenthash:8].css"
      }),
      isProd && new OptimizeCssAssetsPlugin(),
      markoPlugin.browser
    ]
  }),
  compiler({
    name: "Server",
    target: "async-node",
    externals: [/^[^./!]/], // excludes node_modules
    optimization: {
      minimize: false
    },
    output: {
      libraryTarget: "commonjs2",
      path: path.join(__dirname, "dist/server")
    },
    plugins: [
      new webpack.DefinePlugin({
        "process.browser": undefined,
        "process.env.BUNDLE": true
      }),
      new webpack.BannerPlugin({
        banner: 'require("source-map-support").install();',
        raw: true
      }),
      new CSSExtractPlugin({
        filename: "[name].[contenthash:8].css"
      }),
      isDev && spawnedServer,
      markoPlugin.server
    ]
  })
];

// Shared config for both server and client compilers.
function compiler(config) {
  return {
    ...config,
    mode: isProd ? "production" : "development",
    devtool: isProd ? "source-map" : "inline-source-map",
    output: {
      publicPath: "/static/",
      ...config.output
    },
    resolve: {
      extensions: [".js", ".json", ".marko"],
      symlinks: false,
      alias: {
        marko: require("path").dirname(require.resolve("marko/package.json"))
      }
    },
    module: {
      rules: [
        {
          test: /\.marko$/,
          loader: "@marko/webpack/loader"
        },
        {
          test: /\.(less|css)$/,
          use: [CSSExtractPlugin.loader, "css-loader", "less-loader"]
        },
        {
          test: /\.svg/,
          loader: "svg-url-loader"
        },
        {
          test: /\.(jpg|jpeg|gif|png)$/,
          loader: "file-loader",
          options: {
            // File assets from server & browser compiler output to client folder.
            outputPath: "../client"
          }
        }
      ]
    },
    plugins: [...config.plugins, isProd && new CleanWebpackPlugin()].filter(Boolean)
  };
}

Is this something you're interested in working on?

DylanPiercey commented 3 years ago

This has been resolved.