DevExtreme in Nuxt3 failing during build - javascript

I am trying to include DevExtreme UI components into Nuxt 3 project. I took basic Nuxt3 app generated via npx nuxi init nuxt-app and started with bending it.
This is my test component with very basic DevExtreme menu:
<template>
<div id="container">
<dxMenu>
<dxItem icon="home" />
<dxItem text="O aplikaci" />
<dxItem icon="key" />
</dxMenu>
</div>
</template>
<script lang="ts">
import DxMenu, { DxItem } from 'devextreme-vue/menu.js';
import { defineComponent } from 'vue'
export default defineComponent({
components: {
DxMenu, DxItem
}
})
</script>
Then I just render the component in my app.vue. I have no other configuration related to that (apart from importing DevExtreme css file via nuxt.config.ts).
My nuxt.config.ts looks just like this:
import { defineNuxtConfig } from 'nuxt'
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
css : [
'#/assets/css/dx.generic.zdd-scheme.css'
]
})
I was quite successful for dev environement - running npm run dev works like charm. But when I try npm run build it always fails.
The output looks like this:
i Client built in 11430ms 13:38:43
i Building server... 13:38:43
√ Server built in 4482ms 13:38:47
√ Generated public .output/public nitro 13:38:47
start Building server... nitro 13:38:47
ERROR Rollup error: Error: Cannot find module devextreme/ui/menu imported from file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules, file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nuxt/node_modules,
file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nitropack/node_modules, file:///C:/ATOS_Projekty/ZDD/web-ui/app/,
file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/_index.js, file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules,
file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nuxt/, file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules/nuxt/node_modules/_index.js, file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nuxt/node_modules,
file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nitropack/, file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules/nitropack/node_modules/_index.js, file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules/nitropack/node_modules
ERROR Error: Cannot find module devextreme/ui/menu imported from file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules,
file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nuxt/node_modules, file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules/nitropack/node_modules, file:///C:/ATOS_Projekty/ZDD/web-ui/app/, file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules/_index.js, file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules, file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules/nuxt/, file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nuxt/node_modules/_index.js,
file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nuxt/node_modules, file:///C:/ATOS_Projekty/ZDD/web-
ui/app/node_modules/nitropack/, file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nitropack/node_modules/_index.js,
file:///C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nitropack/node_modules
at resolvePath (/C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/mlly/dist/index.mjs:1079:10)
at _resolve (/C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nitropack/dist/shared/nitro.8d0213e3.mjs:304:22)
at Object.resolveId (/C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/nitropack/dist/shared/nitro.8d0213e3.mjs:348:34)
at async resolveId (/C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/rollup/dist/es/shared/rollup.js:21737:26)
at async ModuleLoader.resolveId (/C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/rollup/dist/es/shared/rollup.js:22037:19)
at async /C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/#rollup/plugin-commonjs/dist/es/index.js:773:14
at async Promise.all (index 0)
at async /C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/#rollup/plugin-commonjs/dist/es/index.js:765:30
at async rewriteRequireExpressionsAndGetImportBlock (/C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/#rollup/plugin-commonjs/dist/es/index.js:1312:28)
at async transformCommonjs (/C:/ATOS_Projekty/ZDD/web-ui/app/node_modules/#rollup/plugin-commonjs/dist/es/index.js:1874:23)`
devextreme-vue/menu is importing from devextreme/ui/menu, but it looks like this module is not being passed through during build.
Do I have to declare the dependency somewhere in my code to notify build server to use it? I have tried various things already (like trying to convince Vite (rollup) not to perform tree shaking or to switch to Webpack instead), but always ending up with the same result. But maybe I just fail to do it correctly, I still have to learn a lot about how exactly the things work here. Any help/clues will be appreciated.
This is my package.json in case I shall change or install something there.
{
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare",
"start": "nuxt start"
},
"devDependencies": {
"nuxt": "3.0.0-rc.8"
},
"dependencies": {
"devextreme": "22.1.4",
"devextreme-vue": "22.1.4"
}
}
EDIT: my node is 16.17.0 and npm 8.19.0, maybe the versions are relevant...

So the working solutuion appears to be adding a plugin, in my case named dx.client.ts, but it shouldn't matter, into /plugins folder which imports all necessary components and makes them globally available inside the application:
import { DxButton } from "devextreme-vue/button";
import { DxMenu, DxItem } from 'devextreme-vue/menu';
// the list goes on as the app grows
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp
.component("DxButton", DxButton)
.component("DxMenu", DxMenu)
.component("DxItem", DxItem);
// the list goes on as the app grows
});
I also had to add:
ssr: false
option into nuxt.config.ts, otherwise I ended up with Entry module cannot be external (devextreme-vue). error message during build.
So it has some limitations, but so far it works.
EDIT: it turned out, that while it works fine for some DevExtreme components without further adjustments, some components (like DxForm) also require to disable tree-shaking during Vite build - see how to do it. Otherwise the necessary files are lost in the build process and vague runtime error TypeError: f(...)[t] is not a function appears while rendering the component.
Thanks Stefan (stenet) for the right answer provided here

Related

How to debug import of a javascript function in React?

I have some functions in a javascript file (helpers.js) that are imported into a react file (caller.jsx).
helpers.js:
async function one() {
// ...
}
function two() {
// ...
}
module.exports = { one, two }
caller.jsx:
const { one, two } = require("../utils/helpers")
When I run my local React server (npm run start), everything works fine. I can use the app and it works.
When I run a production build (npm run build) and serve up the javascript from that build, it doesn't work, and there's an error message in the console:
main.d780c23e.chunk.js:1 Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
at Module.<anonymous> (main.d780c23e.chunk.js:1)
at Module.228 (main.d780c23e.chunk.js:1)
at i ((index):3)
at Module.375 (main.d780c23e.chunk.js:1)
at i ((index):3)
at t ((index):3)
at Array.r [as push] ((index):3)
at main.d780c23e.chunk.js:1
And the compiled code in the browser shows the problem at the exports of helpers.js, right at the equals sign (=):
b.exports = {
one: function() { ... },
two: function() { ... }
}
}
I have also tried importing the symbols in caller.jsx:
import { one, two } from "../utils/helpers"
In that case, the production build complains that the symbol is not exported.
./src/hooks/caller.jsx
Attempted import error: 'two' is not exported from '../utils/helpers'.
And if I delete two, then it complains about one.
It seems the CommonJS style of code (with module.exports) isn't working in the ESModule style of code (with import).
However, I have some other files (call them caller2.jsx and helper2.js) where it is working for helper2.js to use module.export and caller2.jsx to use an import statement.
I am flummoxed about how to tell what's going in.
It IS exported, damnit! Why does only the production compiler say it's not?
Versions: node v16.10.0, npm 7.24.0, react 17.0.2, react-scripts 4.0.3.
EDIT: Some build info: we build using npm. Here are the scripts in package.json:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build"
}
As an example, here is the full output of build:
$ npm run build
> myapp#0.1.0 build
> react-scripts build
Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
421.79 KB build/static/js/2.9462f3d3.chunk.js
23.57 KB build/static/css/2.0a9ec390.chunk.css
20.85 KB (+1 B) build/static/js/main.2d21dfa5.chunk.js
2.49 KB build/static/css/main.8d569477.chunk.css
1.73 KB build/static/js/3.2618e91d.chunk.js
1.17 KB build/static/js/runtime-main.2616b467.js
The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.
EDIT 2: We are using hardhat, so we cannot use ESModule exports. See for example this github issue, or this stackoverflow question.

Vuejs / NuxtJs include components from dynamically set directory

I am using NuxtJs / VueJs
I have a problem where by i need to set the path of a component dynamically. Why I hear you ask ?
Well I am creating a set of sites that will use the same basic codebase but only the look and feel will differ and thus for each domain want to load the components from the specific dir. The basic component names etc will remain the same just want to be able to change a few things which are beyond just some v-if statements in the component or css.
eg.
Site1: sites/mysite/HomePageHero.vue
Site2: sites/yoursite/HomePageHero.vue
Now i know about dynamic components but the problem there is i will have to add each sites components to the page every time i create a new site and i dont want to do that. So the more sites I create the bigger that list will get.
I just want to set the site name in the .env add the components to the dir and it all works (or something similar)
So if you take my code below , i need the DYNAMICHERE to be dynamic. There is probably something simple that I am missing.
import HomePageHero from '#/components/sites/DYNAMICHERE/HomePageHero'
Just for clarification as per the first response to this . I have tried doing the following which doesn't obviously work
import HomePageHero from '#/components/sites/' + process.env.THEME . + '/HomePageHero'
I finally got some time to play around with this and I fixed the problem which was best for my solution using the following code
I am using dotenv to define the env variables
const HomePageHero = () => import('#/components/sites/' + process.env.WEBSITE_NAME + '/HomePageHero');
Hattip to this article:
https://vuedose.tips/tips/dynamic-imports-in-vue-js-for-better-performance/
There still may be a cleaner solution but this works well for me.
If you are using laravel then you have 1 option: process.env.YOUR_SITE
This is what we're doing:
declare site names in package.json
use same name for mongodb
import components and use the one that matches mongodb process.env name
"scripts": {
"siteOne": "cross-env MONGO_DB=siteOne API_URL=http://localhost:3000 MONGO_URL=mongodb://localhost NODE_ENV=development nodemon server/index.js --watch server",
"siteTwo": "cross-env MONGO_DB=siteTwo API_URL=http://localhost:3000 MONGO_URL=mongodb://localhost NODE_ENV=development nodemon server/index.js --watch server",
"build_siteOne": "MONGO_DB=siteOne nuxt build",
"build_siteTwo": "MONGO_DB=siteTwo nuxt build",
"start": "node server/index.js",
},
<template>
<div class="footer">
<div class="container">
<component :is="footerComponent"></component>
</div>
</div>
</template>
<script>
import Footer_siteOne from '~/components/Footer_siteOne.vue';
import Footer_siteTwo from '~/components/Footer_siteTwo.vue';
export default {
components: {
Footer_siteOne,
Footer_siteTwo,
},
computed: {
footerComponent: function() {
return 'Footer_'+process.env.MONGO_DB;
}
}
}
</script>

React Native - unexpected token static propTypes when running assmbleRelease, babel plugin doesnt work

I'm trying to compile a release apk in React Native using either
"react-native run-android --variant=release" or
from ./android:
"./gradelw assmbleRelease"
I keep getting the following error:
> :app:bundleReleaseJsAndAssets
ERROR Failed to compile.
./node_modules/native-base-shoutem-theme/src/StyleProvider.js 10:19
Module parse failed: Unexpected token (10:19)
You may need an appropriate loader to handle this file type.
| */
| export default class StyleProvider extends React.Component {
> static propTypes = {
| children: PropTypes.element.isRequired,
...
I've installed this plugin:
https://babeljs.io/docs/en/next/babel-plugin-proposal-class-properties.html
and added it to my babel.config.js:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
'#babel/plugin-proposal-class-properties'
]
};
I've tried creating also a .babelrc file and setting it up. didn't work.
I tried configurating babel through package.json and also it didn't work.
I've tried doing
"react-native start -- --reset-cache"
but nothing helped. I keep getting the same error.
I know the babel.config.js is being read because if I mess around with it I see that the build fails for other reasons.
but a strange thing is that if I remove the file completely, I still get the original error (missing "static propTypes" thing).
why doesn't the plugin work?
Not sure why this happened, but removing "haul" did the trick.
"npm uninstall --save-dev haul"
and remove the added config in app/build.gradle:
project.ext.react = [
cliPath: "node_modules/haul/bin/cli.js"
]

Build a Vue component for "unpkg"

I want to publish my component on unpkg.com. Actually it is there, but not working. I tried to use the same build (umd) as for my npm build, but I think I would need a specific build for unpkg. Here are the relevant parts of my package.json now:
...
"main": "dist/vuePolar.umd.js",
"unpkg": "dist/vuePolar.umd.min.js",
"scripts": {
"package": "vue-cli-service build --target lib --name vuePolar src/components/Polar.vue",
...
}
I suspect I need to build a IIFE instead of an UMD file, but there is nothing like that in my dist folder:
demo.html
vuePolar.common.js
vuePolar.common.js.map
vuePolar.umd.js
vuePolar.umd.js.map
vuePolar.umd.min.js
vuePolar.umd.min.js.map
Any idea how to get a build that works with unkpg?
Actually, it is ok to publish your component as UMD. I had to register my component in the Vue instance, like so:
<div id="app">
<polar :item="3">hoi</polar>
</div>
<script>
var app = new Vue({
el: '#app',
components: { polar: vuePolar},
})
</script>
Now it works. I got confused by an example that did not require the component to be registered.

Meteor + LitElement (Polymer 3) issue with importing

I had an issue with importing the LitElement module into a Meteor project:
I'm starting a new test project with Meteor 1.7+ and am using LitElement for a few components.
I installed Meteor like so:
meteor create meteor-lithtml --release 1.7.1-beta.29 --bare
I installed like so:
meteor npm install --save #polymer/lit-element
My node_modules directory looks like so:
My package.json file:
{
"name": "myapp",
"private": true,
"scripts": {
"start": "meteor run"
},
"dependencies": {
"#babel/runtime": "^7.0.0-beta.56",
"#polymer/lit-element": "^0.5.2",
"#vaadin/router": "^1.0.0",
"meteor-node-stubs": "^0.4.1",
"redux": "^4.0.0"
},
"meteor": {
"mainModule": {
"client": "client/index.js",
"server": "server/index.js"
}
}
}
The typical way I see lit-element imported is not working...
Just adding an index.js file and importing the lit-element module generates errors. If I remove the import from the index.js file, the errors go away.
\\ client\index.js
import { LitElement, html } from '#polymer/lit-element';
The very first error:
Uncaught SyntaxError: Unexpected token {
modules.js?hash=182125a3fa97eaa24f6d313584ca593c3aed2103:984
Points to this location:
Expanding node_modules to look into this file:
Why am I getting the unexpected { token?
NOTE: I'm asking this question here just in case a Meteor user stumbles by with the same issue and needs help.
Just in case we have any more Meteor users stop by with an issue like this, here are the references to the explanation & solution:
explanation: https://forums.meteor.com/t/litelement-import-litelement-html/45042/8?u=aadams
solution: https://github.com/aadamsx/meteor-lithtml/pull/1

Categories

Resources