-1

I'm building a multi-page typescript webapp using open-WC as the base, which came with rollup as the default build tool. We have a handful of assets included in our application and I'm having trouble getting them into the actual dist folder without using @web/rollup-plugin-copy - from basic googling, this seems to be something that plenty of rollup plugins support doing automatically, but I've bashed my head against this for a while without success.

The image reference is a pretty simple <img alt="image" src="assets/image.jpg" /> in an html template literal in a .ts file, which is used as a custom HTML element in a bunch of other pages

The component:

@customElement("this-component")
export class ThisComponent extends connect(store)(LitElement) {
[...]
  render() {
    [...]
    return html`
      [...]
      <img alt="image" src="assets/image.jpg" />
      [...]
    `;
  }
[...]
}

The usage:

<!DOCTYPE html>
<html lang="en">
  [...]
  <body>
    <the-component></the-component>
    <another-component></another-component>

    <script type="module" src="./out-tsc/src/TheComponent.js"></script>
    <script type="module" src="./out-tsc/src/AnotherComponent.js"></script>
  </body>
</html>

This may already be wildly incredibly obvious but I'm not an experienced frontend dev so I imagine huge parts of this are not idiomatic. Any advice on how to get this working in a more "natural" way would be ideal.

Project structure:

root/
<various html files>
styles.css
favicon.ico
<various project root files>
rollup.config.mjs
web-dev-server.config.mjs
tsconfig.json
- assets
- fonts
- src
-- *.ts

npm scripts:

"start": "tsc --outDir ./out-tsc && concurrently -k -r \"tsc --outDir ./out-tsc --watch --preserveWatchOutput\" \"wds\""
"build": "rimraf dist && tsc && cp -r dist/out-tsc . && rollup -c rollup.config.mjs && npm run analyze -- --exclude dist",
"start:build": "web-dev-server --root-dir dist --app-index index.html --open",

tsconfig:

{
  "compilerOptions": {
    "target": "es2018",
    "module": "esnext",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "lib": ["es2017", "dom"],
    "strict": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "outDir": "dist/out-tsc",
    "sourceMap": true,
    "inlineSources": true,
    "rootDir": "./",
    "incremental": true
  },
  "include": ["**/*.ts", "src/declaration.d.ts", "src/assets", "src/fonts"]
}

Rollup config:

import { copy } from "@web/rollup-plugin-copy";
import path from "path";
import nodeResolve from "@rollup/plugin-node-resolve";
import replace from "@rollup/plugin-replace";
import babel from "@rollup/plugin-babel";
import typescript from "@rollup/plugin-typescript";
import { importMetaAssets } from "@web/rollup-plugin-import-meta-assets";
import summary from "rollup-plugin-summary";
import terser from "@rollup/plugin-terser";
import { generateSW } from "rollup-plugin-workbox";
import image from "@rollup/plugin-image";
import { rollupPluginHTML as html } from "@web/rollup-plugin-html";

import dotenv from "dotenv";

dotenv.config();

const nodeEnv = process.env.NODE_ENV || "production";
const appUrl = process.env.APP_URL;

if (!appUrl) {
  throw new Error("APP_URL environment variable required to build");
}

export default {
  input: "*.html",
  output: {
    entryFileNames: "[hash].js",
    chunkFileNames: "[hash].js",
    assetFileNames: "[hash][extname]",
    format: "es",
    dir: "dist",
    sourcemap: true
  },
  preserveEntrySignatures: false,

  plugins: [
    image(),
    /** Resolve bare module imports */
    nodeResolve(),
    typescript(),
    /** Enable using HTML as rollup entrypoint */
    html({
      minify: true,
      injectServiceWorker: true,
      serviceWorkerPath: "dist/sw.js"
    }),
    /** Minify JS */
    terser(),
    /** Bundle assets references via import.meta.url */
    importMetaAssets(),
    /** Compile JS to a lower language target */
    babel({
      babelHelpers: "bundled",
      presets: [
        [
          "@babel/preset-env",
          {
            targets: [
              "last 3 Chrome major versions",
              "last 3 Firefox major versions",
              "last 3 Edge major versions",
              "last 3 Safari major versions"
            ],
            modules: false,
            bugfixes: true
          }
        ]
      ],
      plugins: [
        [
          "babel-plugin-template-html-minifier",
          {
            modules: { lit: ["html", { name: "css", encapsulation: "style" }] },
            failOnError: false,
            strictCSS: true,
            htmlMinifier: {
              collapseWhitespace: true,
              conservativeCollapse: true,
              removeComments: true,
              caseSensitive: true,
              minifyCSS: true
            }
          }
        ]
      ]
    }),
    /** Create and inject a service worker */
    generateSW({
      globIgnores: ["polyfills/*.js", "nomodule-*.js"],
      // where to output the generated sw
      swDest: path.join("dist", "sw.js"),
      // directory to match patterns against to be precached
      globDirectory: path.join("dist"),
      // cache any html js and css by default
      globPatterns: ["**/*.{html,js,css,webmanifest}"],
      skipWaiting: true,
      clientsClaim: true,
      runtimeCaching: [{ urlPattern: "polyfills/*.js", handler: "CacheFirst" }]
    }),
    replace({
      "process.env.NODE_ENV": JSON.stringify(nodeEnv),
      "process.env.APP_URL": JSON.stringify(appUrl),
      preventAssignment: true
    }),
    copy({
      patterns: ["assets/**/*", "fonts/**/*"]
    }),
    summary()
  ]
};

ChickenWing
  • 639
  • 9
  • 24

0 Answers0