Coder Social home page Coder Social logo

esbuild-plugin-vue3's Introduction

esbuild-plugin-vue3

npm version

esbuild plugin for resolving and loading Vue.js 3 SFCs. This plugin is meant to mimick the default Vue CLI behaviour, for example it supports path aliases defined in the tsconfig.json file.

Install:

npm i -D esbuild-plugin-vue3

Supported

  • HTML and Pug <template>
  • JavaScript and TypeScript <script> and <script setup> (the latter is still experimental)
  • CSS, SCSS and SASS <style>
  • Path aliases from tsconfig.json, e.g. import "@/Component.vue" resolves to import "../../Component.vue
  • Emit HTML file and inject output CSS and JS files

Usage

Simple usage, this will resolve all .vue imports and load its parts independently. By default path aliases will be loaded from the tsconfig.json file, if any.

const esbuild = require("esbuild")
const vuePlugin = require("esbuild-plugin-vue3")

esbuild.build({
    entryPoints: ["src/app.ts"],
    bundle: true,
    outfile: "dist/app.js",
    plugins: [vuePlugin()]
})

More advanced usage, generating HTML file:

const esbuild = require("esbuild")
const vuePlugin = require("esbuild-plugin-vue3")

esbuild.build({
    entryPoints: ["src/app.ts"],
    bundle: true,
    outfile: "dist/app.js",
    entryNames: '[dir]/[name]-[hash]',
    metafile: true,
    plugins: [vuePlugin({
        generateHTML: "src/index.html"
        // Or:
        generateHTML: {
            sourceFile: "src/index.html",
            pathPrefix: "assets/",
            preload: [{ href: "https://example.com/my-external.css", as: "stylesheet" }]
        }
    })]
})

The library is still not thoroughly tested, use at your own risk.

esbuild-plugin-vue3's People

Contributors

danieletulone avatar markeeaton avatar pgbross avatar pipe01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

esbuild-plugin-vue3's Issues

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ warning since vue version 3.4.*

Hello, since upgrading vue to latest version (3.4.15) I'm getting the following warning:

image

I've tried passing VUE_PROD_HYDRATION_MISMATCH_DETAILS flag to the vuePlugin() options object but it didn't work. Checking the source for the Options.ts I don't think this flag has been implemented in this plugin since it's relatively new.

Docs can be found here: https://vuejs.org/api/compile-time-flags

Am I doing something wrong? Would appreciate the help. Cheers

Inline css

Hi, I'm using esbuild and esbuild-plugin-vue3 in a monorepo project.
Everything seems to works well but not for some styles. I'm using tailwind so the <style> blocks in my project are about 10.
Is there an option to inline css?

Dependencies of Sass dependencies aren't loading

Summary
If you load a scss dependency with @use or @forward (probably @import as well), and that scss dependency has a dependency on a node_module, you get a
[ERROR] Can't find stylesheet to import. on the imported node_module file.

I'm guessing it's an issue with the includePaths or importers
https://github.com/pipe01/esbuild-plugin-vue3/blob/master/src/index.ts#L268

When I import the files directly from node_modules that it's saying it can't find, then it works.

Expected Behaviour
If you have an import/use/forwards in a scss file that's being imported in a vue SFC, it should not throw an error and the scss should be made available in that scope.

Specific tsconfig path

I found the plugin reading tsconfig with fs.promises.readFile('tsconfig.json'), so I have to use process.chdir(...) to specify the tsconfig file I want.

It will be nice if the plugin reads the tsconfig file according to the tsconfig option of esbuild.

Migrating from vue2 to vue3

Hi,

Do you have any advice/recommendations for using this plugin to migrate from vue2 to vue3?

There doesn't seem to be much support for completing this migration using esbuild as the build tool. But perhaps I am missing something.

Thanks!

Build errors, no matching export.

Thanks for taking initiative with this library! I have SFCs that use <script lang="ts"> and I get this error when trying to build with your plugin:

> sfc-template:/home/mikob/workspace/lipsurf/chrome-extension/src/components/tooltip.vue?type=template:1:36: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "createElementVNode"
    1 │ import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
      ╵                                     ~~~~~~~~~~~~~~~~~~

 > sfc-template:/home/mikob/workspace/lipsurf/chrome-extension/src/components/tooltip.vue?type=template:1:79: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "normalizeClass"
    1 │ import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
      ╵                                                                                ~~~~~~~~~~~~~~

 > sfc-template:/home/mikob/workspace/lipsurf/chrome-extension/src/components/tooltip.vue?type=template:1:139: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "createElementBlock"
    1 │ import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
      ╵                                                                                                                                            ~~~~~~~~~~~~~~~~~~

 > sfc-template:/home/mikob/workspace/lipsurf/chrome-extension/src/components/shortcut-adder.vue?type=template:1:9: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "normalizeClass"
    1 │ import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, createVNode as _createVNode, createTextVNode as _createTextVNode, toDisplayString as _toDisplayString, vModelText as _vModelText, withDirectives as _withDir...
      ╵          ~~~~~~~~~~~~~~

 > sfc-template:/home/mikob/workspace/lipsurf/chrome-extension/src/components/shortcut-adder.vue?type=template:1:44: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "createElementVNode"
    1 │ import { normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, createVNode as _createVNode, createTextVNode as _createTextVNode, toDisplayString as _toDisplayString, vModelText as _vModelText, withDirectives as _withDir...
      ╵                                             ~~~~~~~~~~~~~~~~~~

 > sfc-template:/home/mikob/workspace/lipsurf/chrome-extension/src/components/shortcut-adder.vue?type=template:1:422: error: No matching export in "node_modules/vue/dist/vue.runtime.esm-bundler.js" for import "createElementBlock"
    1 │ ...Directives as _withDirectives, vModelCheckbox as _vModelCheckbox, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, vShow as _vShow, Transition as _Transition, withModifiers as _withModifiers, createCommentVNode as _createCommentVNo...

Not support image handling

I'm trying to import an image in SFC, but I got this error:
22:58:48 js.1 | ✘ [ERROR] Could not resolve "./images/opencsg_logo.png"

<script lang="ts" setup>
import { ref } from 'vue'
import logo from './images/logo.png'
</script>

not sure how does this plugin handle this?

esbuild/lib/main.d.ts has been updated and it causes TypeScript error

Hello,

TypeScript throws error on plugins: [vuePlugin()].
In my opinion, It is caused by mismatching files in the plugin
esbuild-plugin-vue3/node_modules/esbuild/lib/main.d.ts ([email protected])
and in esbuild
esbuild/lib/main.d.ts ([email protected])

When I replace the content of the first file, the problem goes away.

The log:

    return new TSError(diagnosticText, diagnosticCodes, diagnostics);
           ^
TSError: ⨯ Unable to compile TypeScript:
config/build/esbuild-config.ts:24:13 - error TS2322: Type 'import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild-plugin-vue3/node_modules/esbuild/lib/main").Plugin' is not assignable to type 'import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild/lib/main").Plugin'.
  Types of property 'setup' are incompatible.
    Type '(build: import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild-plugin-vue3/node_modules/esbuild/lib/main").PluginBuild) => void | Promise<void>' is not assignable to type '(build: import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild/lib/main").PluginBuild) => void | Promise<void>'.
      Types of parameters 'build' and 'build' are incompatible.
        Type 'import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild/lib/main").PluginBuild' is not assignable to type 'import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild-plugin-vue3/node_modules/esbuild/lib/main").PluginBuild'.
          The types of 'initialOptions.loader' are incompatible between these types.
            Type '{ [ext: string]: import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild/lib/main").Loader; } | undefined' is not assignable to type '{ [ext: string]: import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild-plugin-vue3/node_modules/esbuild/lib/main").Loader; } | undefined'.
              Type '{ [ext: string]: import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild/lib/main").Loader; }' is not assignable to type '{ [ext: string]: import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild-plugin-vue3/node_modules/esbuild/lib/main").Loader; }'.
                'string' index signatures are incompatible.
                  Type 'import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild/lib/main").Loader' is not assignable to type 'import("/home/stas/work/test/js/js_builder_test_1/node_modules/esbuild-plugin-vue3/node_modules/esbuild/lib/main").Loader'.
                    Type '"empty"' is not assignable to type 'Loader'.

24   plugins: [vuePlugin()]

Unable to import TypeScript types from another file

I'm trying to import TypeScript types from another file, yet I get this error:

✘ [ERROR] [@vue/compiler-sfc] No fs option provided to `compileScript` in non-Node environment. File system access is required for resolving imported types.

src/app.vue
12 |  import { Settings } from './settings';
13 |  
14 |  const props = defineProps<Settings>()
   |                            ^^^^^^^^
15 |  const emit = defineEmits<{ updateTimetable: [] }>()
16 |  </script> [plugin vue]

    src/view.ts:5:16:
      5 │ import App from './app.vue';
        ╵                 ~~~~~~~~~~~

  This error came from the "onLoad" callback registered here:

    node_modules/esbuild-plugin-vue3/dist/index.js:218:34:
      218 │                             build.onLoad({ filter: /\.vue$/ }, function (args) { return cache.get([args.path, args.namespace], function () { return __awaiter(_this, void 0, void 0, function () {
          ╵                                   ~~~~~~

    at /Users/***/node_modules/esbuild-plugin-vue3/dist/index.js:218:35
    at step (/Users/***/node_modules/esbuild-plugin-vue3/dist/index.js:67:23)
    at Object.next (/Users/***/node_modules/esbuild-plugin-vue3/dist/index.js:48:53)
    at fulfilled (/Users/***/node_modules/esbuild-plugin-vue3/dist/index.js:39:58)

Unable to import default and specific objects form a component

Hello, I'm trying to port my app from Webpack to ESBuild and see the following problem with imports resolving:

module.vue:
<template></template>
<script>
export const FOO = 'foo';
export default {
  data() {
    return {
      bar: 'bar'
    }
  }
}
</script>

app.js:
import Module, {FOO} from './module.vue';

console.log('Module: ', Module);
console.log('FOO: ', FOO);

Error:

Error: Build failed with 1 error:
test2/app.js:1:16: ERROR: No matching export in "test2/module.vue" for import "FOO"

This kind of import does not work in the app. Is there any option to configure the plugin to resolve the problem?

Add support for `defineCustomElement` styles property

With the release of vue 3.2, defineCustomElement is officially supported and it has a specialized property called styles that can be added on that will append the styles in the shadow dom.

Sadly, this property is not handled in the compiler but in the bundler (here is vite's method for dealing with it):

https://github.com/vitejs/vite/blob/1809fccab6267a68336b8374428a88c0514f4ac7/packages/plugin-vue/src/main.ts#L340-L345

We are looking to be able to leverage using custom elements at work with vue3, and we are using your plugin as part of our build process. Would it be possible to get some form of support for appending styles for custom elements?

Let me know if you would like more information (I can also attempt helping to make a PR for it.)

Html generation can insert too many <script> elements

When generating an html file it can insert too many <script> elements.

Currently for each asset in the metafile outputs the code uses script.insertAfter($("body :last-child")), but this selects all elements that are the last child of their parent.

For example:

<body class="mdc-typography">
    <div id="app">                                                    <!-- match -->
      <div class="home-splash">                                       <!-- match -->
        <div class="home-splash-logo">
          <img src="/media/INIApp-logo-128.png" alt="" />             <!-- match -->
        </div>
        <div class="loader">                                          <!-- match -->
          <svg viewBox="0 0 32 32" width="32" height="32">            <!-- match -->
            <circle class="spinner" cx="16" cy="16" r="14" fill="none"></circle>   <!-- match -->
          </svg>
        </div>
      </div>
    </div>
  </body>

with the selector $("body :last-child")) it has the 6 matches marked. This results in each script asset being referenced multiple times.

Using $("body").append(script) will add the script as a last child of body.

How can I use Typescript in templates?

I got an error when building something like :prop="val!" in a SFC template. Does/Will this plugin support Typescript in templates? Thank you for the nice plugin!

Compatibility with esbuild>=0.14.4

Esbuild v0.4.14 changes the way export default works to match vue-loader behavior.
From this version on the plugin doesn't work anymore (I'm using it with latest vue@next + vue-router@next).
Issue needs further investigation but I did a simple diff of the bundle generated by ==0.14.3 and >=0.14.4:

--- 0.14.3
+++ 0.14.4 - 0.14.8
 var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
 var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
 var __esm = (fn, res) => function __init() {
-  return fn && (res = (0, fn[Object.keys(fn)[0]])(fn = 0)), res;
+  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
 };
 var __commonJS = (cb, mod) => function __require() {
-  return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
 };
 var __export = (target, all) => {
-  __markAsModule(target);
   for (var name in all)
     __defProp(target, name, { get: all[name], enumerable: true });
 };
-var __reExport = (target, module, desc) => {
+var __reExport = (target, module, copyDefault, desc) => {
   if (module && typeof module === "object" || typeof module === "function") {
     for (let key of __getOwnPropNames(module))
-      if (!__hasOwnProp.call(target, key) && key !== "default")
+      if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
         __defProp(target, key, { get: () => module[key], enumerable: !(desc = __getOwnPropDesc(module, key)) || desc.enumerable });
   }
   return target;
 };
-var __toModule = (module) => {
-  return __reExport(__markAsModule(__defProp(module != null ? __create(__getProtoOf(module)) : {}, "default", module && module.__esModule && "default" in module ? { get: () => module.default, enumerable: true } : { value: module, e
+var __toESM = (module, isNodeMode) => {
+  return __reExport(__markAsModule(__defProp(module != null ? __create(__getProtoOf(module)) : {}, "default", !isNodeMode && module && module.__esModule ? { get: () => module.default, enumerable: true } : { value: module, enumerabl
 };

 // node_modules/@vue/shared/dist/shared.esm-bundler.js

maybe this can help in identifying/resolving the problem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.