Does vite handle module imports differently during development versus production?

I am currently working on incorporating the jointjs library into a Vue application. It is being declared as a global property in Vue and then modified accordingly. Below is a basic example of what I am trying to achieve:

import Vue from 'vue';
import * as joint from 'jointjs';
import App from '@/App.vue';

// custom connectors are required
let customConnectors={
    f: function() {}
}

Vue.use({
    install: function (Vue) {
        // In development, the following methods work:
        //    _.assign(joint.connectors, customConnectors);
        //    _.each(customConnectors, (item, key) => { joint.connectors[key] = item;});
        // and this:
        //    for (const connector in customConnectors) {
        //       joint.connectors[connector] = customConnectors[connector];
        //     }
        // However, none of these methods work in production, throwing errors about joint being a constant or not extensible
        // The statement below causes a build error regarding 'f' not being exported by jointjs/src/connectors
        //    joint.connectors['f'] = customConnectors['f'];
        // This one gives the same error but runs without any issue; However, it only works when minified, potentially just removing the statement 
        joint.connectors.f = customConnectors.f; 
        Vue.joint = joint;
    }
});

let app = new Vue({
  joint,
  render: h => h(App)
}).$mount('#app');

All the examples mentioned in the comments above function well during development. None of them work once built for production.

The issue appears to be that in production, the jointjs import is treated as a constant whereas in development it is not?

Below is my vite configuration:

import { defineConfig } from 'vite';
import { createVuePlugin } from 'vite-plugin-vue2';
import ViteComponents from 'vite-plugin-components';
import path from 'path';

export default defineConfig({
  plugins: [ 
      createVuePlugin(), 
      ViteComponents({
      })
    ],
  server: {
    port: 8080
  },
  resolve: {
    alias: [
      {
        find: '@',
        replacement: path.resolve(__dirname, 'src')
      }
    ]
  },
  build: {
    chunkSizeWarningLimit: 600,
  }
});

Is this behavior intentional? Am I missing a build option?

If needed, here is a link to a repository with a reproduction: https://github.com/dovrosenberg/vite-test

Thank you!

Answer №1

Special thanks to the helpful tips provided by Estus Flask in the comments, I have successfully implemented this solution.

My approach involved using rollup to convert jointjs into an ES module initially.

To begin, run npm i --save-dev rollup-plugin-commonjs

It's worth noting that Rollup should already be installed as vite utilizes it.

A configuration file named rollup.config.js was created in the root directory of the project:

import commonjs from 'rollup-plugin-commonjs';

export default {
  input: 'node_modules/jointjs/joint.mjs',
  output: {
    file: 'src/plugins/jointjsESM.js',
    format: 'es',
    freeze: false,  // crucial for preventing everything from being constant
  },
  plugins: [
    commonjs({
      extensions: [ '.js', '.mjs' ],
      ignoreGlobal: false,
      sourceMap: false,
    }),
  ],
};

The value assigned to output.file can be adjusted based on where you want the resulting module to reside.

You can then set up a package.json script (or utilize npx) to execute rollup --config rollup.config.js

This action generates the new module file at the specified output.location. This script can be executed prior to vite build within a build pipeline.

Instead of importing with import * as joint from 'jointjs', you'll import from the generated output file and manually assemble the joint object with the necessary components. For instance:

import {
   g,
   dia,
   shapes,
   connectors,
} from '@/plugins/jointjsESM.js';

let joint = { g, dia, shapes, connectors };

In addition, you have the option to designate jointjs solely as a dev dependency since it isn't utilized during the build process.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error when publishing with npm: Authorization required for this machine. Please authenticate using npm adduser command

After upgrading to node v18 and npm v9, I am attempting to execute npm publish on a package. Unfortunately, I encounter the following error: To proceed, you must be logged in to . You are required to authorize this machine by using npm adduser. This is m ...

What is the best way to transform React API data into props that can be utilized in different components?

I've been struggling with this issue for quite some time now, unable to understand how to manipulate the data in a way that allows me to use it in other components. Although I can display the data correctly, I'm advised to structure it within a f ...

The switch statement is not functioning properly when the button is pressed

I am trying to trigger an alert inside a switch statement when I click a button, but for some reason, it is not working. Even if I simply have an alert in the previous function, there is no output on my website. What could be causing this issue? Here is ...

Attempting to send numerous identifiers in an API request

I encountered a problem while working on a function in Angular that involves pulling data from an API. My goal is to enhance a current segment to accommodate multiple IDs, but I face difficulties when attempting to retrieve more than one ID for the API que ...

The battle between Iteration and Recursion: Determining the position of a point in a sequence based

One of the challenges I'm facing involves a recursive function that takes a point labeled {x,y} and then calculates the next point in the sequence, recursively. The function in question has the following structure: var DECAY = 0.75; var LENGTH = 150 ...

Creating stunning 3D animations using Canvas

I am knowledgeable about Canvas 2D context, but I would like to create a 3D animation similar to this example. Would using the Three.js library be the most suitable option for this type of animation? Any recommendations for tutorials or documentation tha ...

Merge text inputs to preview content prior to form submission

I've been on the hunt for a solution to display the collective values entered into multiple text box fields as they are being typed. Currently, I have 6 text boxes (description1, description2, description3, description4, description5, description6) wh ...

ESLint has detected a potential race condition where the `user.registered` variable could be reassigned using an outdated value. This issue is flagged by the `require-atomic-updates` rule

I have developed an asynchronous function which looks like this: let saveUser = async function(user){ await Database.saveUser(user); if (!user.active) { user.active = true; //storedUs ...

Is there a way to merge all this data into a single Object?

This particular situation is quite complex. Let's consider the following scenario: I have two JavaScript objects that are fetched via REST calls, using two different callbacks. So, we have: call1() - POST method - parsed JSON to JavaScript object, ...

Ways to transfer a v-model from the parent component to a template

I'm currently in the process of designing the user interface for a search page and I want to utilize components to help with code reusability. However, I am facing a challenge in figuring out how to pass the model of the page to the search component. ...

A step-by-step guide on sending a fetch request to TinyURL

I have been attempting to send a post request using fetch to tinyURL in order to shorten a URL that is generated on my website. The following code shows how I am currently writing the script, however, it seems like it's not returning the shortened URL ...

Passing a PHP variable between PHP files with the help of jQuery

I'm facing a minor issue. I'm trying to pass a PHP variable from one PHP file to another using setInterval. However, I'm unsure of how to include the PHP variable in my jQuery code. Here is the content of first.php: <?php $phpvariable= ...

Is there a way to effectively transfer both Vertex and Face normals to a Three.js shader?

It seems that the THREE.Geometry methods, .computeFaceNormals() & .computeVertexNormals(), assign values to a built-in attribute array called "normal." If I want to utilize both vertex- & face-normals in one shader, I need to: Calculate face-normals ...

A customizable and adaptable Tetris-inspired CSS design perfect for any screen size

If we imagine having a block like this: <div class="block"></div> There are different sizes of the block: <div class="block b1x1"></div> <div class="block b2x1"></div> <div class="block b1x2"></div> For i ...

Display the page for 10 seconds continuously in a loop

I am currently developing a Node JS guessing game where data is collected on the back-end and sent to the front-end to start the game. The data consists of 10 levels, allowing the game to operate on a single page. Each level lasts for 10 seconds. Once the ...

Unexpected symbol in JSON parsing with JavaScript

let information; $.ajax({ url: link, type: 'POST', dataType: "json", success: function (data, textStatus) { information = data; alert(data.name); } }); I am attempting to retrieve JSON-encoded data from a spe ...

Preserve the height of the previous div following an AJAX request

I am currently facing an issue where I have a script that utilizes ajax to receive a response containing a cart string (html code) with items from the cart. Inside the response handler, there is another script that sets the height of each div in the cart s ...

executing the following event in Node.js

Is it feasible to execute only a portion of the code on each iteration of the event loop in an application where requests can take a second or two? Consider the following scenario: function foo() { ...critical code... ...start processing the next ...

Is it possible to calculate a variable within a dataset using existing data as a reference point?

Is there a way to dynamically compute some of the data variables in a Vue instance by referencing other variables and tracking their changes? new Vue({ el: '#root', data: { x: 1, y: x + 1 } }) <script src="https://cdnjs.cloudf ...

Is jQuery noConflict really necessary?

I am a student who doesn't have much experience in the field of code development. I currently have my website up and running and I would like to add jetmenu to my template (that's all!). Here is the link to jetmenu: http://codecanyon.net/item/j ...