esbuild-plugin-vue3 icon indicating copy to clipboard operation
esbuild-plugin-vue3 copied to clipboard

Compatibility with esbuild>=0.14.4

Open franklx opened this issue 3 years ago • 6 comments
trafficstars

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.

franklx avatar Dec 23 '21 09:12 franklx

I've tried with esbuild 0.14.8 and vue 3.2.26 and it seems to work, do you have a small reproduction project I can test?

pipe01 avatar Dec 23 '21 12:12 pipe01

Sure, i put up a test repo . It contains 2 commits: the working version with 0.14.3 and the non-working version with latest esbuild. You should simply run "node build.mjs" to create asset files. The non-working version dumps this in console:

[Vue warn]: Component is missing template or render function. 
  at <Anonymous onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView key="/demo" > 
  at <Layout>

The working version loads the component at /demo correctly.

franklx avatar Dec 23 '21 13:12 franklx

My understanding of the (messy) import/export mechanism is poor but I made it work by explicitly exporting render and setup functions:

const setup = script.setup;
export { script as default, render, setup }; 

default export must be kept and even the setup function must be explicitly exported. I did the modification in my fork: @franklx/esbuild-plugin-vue3 Maybe this can help you understanding what's going on...

franklx avatar Jan 05 '22 15:01 franklx

Solution is actually very simple: generated script must use cjs export mechanism:

- code += "export default script;";
+ code += "module.exports = script";

My fork includes this change and other tweaks and the replacement for the eval function used to read tsconfig.json: I can create a cleaner PR for you to merge it.

franklx avatar Jan 06 '22 10:01 franklx

Sorry, just checked out your fork. It's odd because it works fine for me if I replace your fork with my package in your project, I don't get any kind of errors. What node version are you running?

pipe01 avatar Jul 19 '22 16:07 pipe01

Now I'm using node v16 but maybe in January I was using v14 (or even v12). I'm still using my fork: I'll try using yours and let you know.

franklx avatar Jul 19 '22 17:07 franklx