Dependency exports an empty object when bundling component library with Rollup - rollupjs

I'm trying to use rollup to build my React component library. The bundle step completes with a few warnings, however, when I actually try to use it in a Next.js application, I get many "X is not a function" errors when visiting the website. It seems to happen because some dependencies inside the _virtual directory are empty:
For example, this is dist/_virtual/d3-time-format.js (my library uses #visx/scale, which depends on d3-scale, which in turn depends on d3-time-format)
var d3TimeFormat = {exports: {}};
export { d3TimeFormat as d };
//# sourceMappingURL=d3-time-format.js.map
As you can see above, the exports is an empty object, so I get the error "format is not a function". This happens also with other modules, like prop-types (my dependencies depend on it).
This is my rollup.config.js:
import { babel } from '#rollup/plugin-babel';
import commonjs from '#rollup/plugin-commonjs';
import resolve from '#rollup/plugin-node-resolve';
import typescript from '#rollup/plugin-typescript';
import svgr from '#svgr/rollup';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
function bundle(inputPath) {
return {
input: inputPath,
output: [
{
dir: `./dist`,
format: 'esm',
sourcemap: true,
preserveModules: true,
preserveModulesRoot: 'src',
},
],
plugins: [
peerDepsExternal(),
commonjs(),
resolve(),
svgr({
icon: true,
replaceAttrValues: { '#000': '{props.color}' },
svgProps: { fill: 'currentColor' },
}),
typescript(),
babel({
babelHelpers: 'runtime',
exclude: /node_modules/,
extensions: ['.js', '.ts', '.tsx'],
}),
],
};
}
export default [bundle('./src/index.ts')];
When bundling I get these warnings, not sure if they are relevant:
Would appreciate some guidance on what the files inside _virtual are and why they are generated with an empty object. Thanks#

Related

Nuxt 3 environment variables for static site [duplicate]

I have .env file in the project root, and in my nuxt config I am using variables to configure ReCaptcha like this:
import dotenv from 'dotenv'
dotenv.config()
export default {
modules: [
['#nuxtjs/recaptcha', {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
size: 'compact'
}],
]
}
and in .env like this:
RECAPTCHA_SITE_KEY=6L....
but the application always failed with console log error:
ReCaptcha error: No key provided
When I hard-code ReCaptcha key directly like that: siteKey: 6L.... app start working, so I guess the problem is with reading .env props in nuxt.config
do you have any idea how to fix it?
EDIT:
I tried update my nuxt.config by #kissu recommendation and by example which I found here: https://www.npmjs.com/package/#nuxtjs/recaptcha
so there is new nuxt.config which also not working:
export default {
modules: [
'#nuxtjs/recaptcha',
],
publicRuntimeConfig: {
recaptcha: {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
size: 'compact'
}
}
}
If your Nuxt version is 2.13 or above, you don't need to use #nuxtjs/dotenv or anything alike because it is already backed into the framework.
To use some variables, you need to have an .env file at the root of your project. This one should be ignored by git. You can then input some keys there like
PUBLIC_VARIABLE="https://my-cool-website.com"
PRIVATE_TOKEN="1234qwer"
In your nuxt.config.js, you have to input those into 2 objects, depending of your use case, either publicRuntimeConfig or privateRuntimeConfig:
export default {
publicRuntimeConfig: {
myPublicVariable: process.env.PUBLIC_VARIABLE,
},
privateRuntimeConfig: {
myPrivateToken: process.env.PRIVATE_TOKEN
}
}
Differences: publicRuntimeConfig can basically be used anywhere, while privateRuntimeConfig can only be used during SSR (a key can only stay private if not shipped to the browser).
A popular use case for the privateRuntimeConfig is to use it for nuxtServerInit or during the build process (either yarn build or yarn generate) to populate the app with headless CMS' API calls.
More info can be found on this blog post: https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config/
Then, you will be able to access it into any .vue file directly with
this.$config.myPublicVariable
You access it into Nuxt's /plugins too, with this syntax
export default ({ $axios, $config: { myPublicVariable } }) => {
$axios.defaults.baseURL = myPublicVariable
}
If you need this variable for a Nuxt module or in any key in your nuxt.config.js file, write it directly with
process.env.PRIVATE_TOKEN
Sometimes, the syntax may differ a bit, in this case refer to your Nuxt module documentation.
// for #nuxtjs/gtm
publicRuntimeConfig: {
gtm: {
id: process.env.GOOGLE_TAG_MANAGER_ID
}
},
PS: if you do use target: server (default value), you can yarn build and yarn start to deploy your app to production. Then, change any environment variables that you'd like and yarn start again. There will be no need for a rebuild. Hence the name RuntimeConfig!
Nuxt3 update
As mentioned here and in the docs, you can use the following for Nuxt3
nuxt.config.js
import { defineNuxtConfig } from 'nuxt3'
export default defineNuxtConfig({
runtimeConfig: {
public: {
secret: process.env.SECRET,
}
}
}
In any component
<script setup lang="ts">
const config = useRuntimeConfig()
config.secret
</script>
In a composable like /composables/test.js as shown in this comment
export default () => {
const config = useRuntimeConfig()
console.log(config.secret)
}
Here is the official doc for that part.
You can also use the env property with Nuxt
nuxt.config.js:
export default {
// Environment variables
env: {
myVariable: process.env.NUXT_ENV_MY_VAR
},
...
}
Then in your plugin:
const myVar = process.env.myVariable
It's very easy. Providing you an example with axios/nuxt
Define your variable in the .env file:
baseUrl=http://localhost:1337
Add the variable in the nuxt.config.js in an env-object (and use it in the axios config):
export default {env: {baseUrl: process.env.baseUrl},axios: {baseURL: process.env.baseUrl},}
Use the env variable in any file like so:
console.log(process.env.baseUrl)
Note that console.log(process.env) will output {} but console.log(process.env.baseUrl) will still output your value!
For nuxt3 rc11, in nuxt.conf.ts file:
export default defineNuxtConfig({
runtimeConfig: {
public: {
locale: {
defaultLocale: process.env.NUXT_I18N_LOCALE,
fallbackLocale: process.env.NUXT_I18N_FALLBACK_LOCALE,
}
}
},
...
and in .env file:
NUXT_I18N_LOCALE=tr
NUXT_I18N_FALLBACK_LOCALE=en
public: is very important otherwise it cannot read it and gives undefined error.
For v3 there is a precise description in the official docs
You define a runtimeConfig entry in your nuxt.config.[ts,js] which works as initial / default value:
export default defineNuxtConfig({
runtimeConfig: {
recaptchaSiteKey: 'default value' // This key is "private" and will only be available within server-side
}
}
You can also use env vars to init the runtimeConfig but its written static after build.
But you can override the value at runtime by using the following env var:
NUXT_RECAPTCHA_SITE_KEY=SOMETHING DYNAMIC
If you need to use the config on client-side, you need to use the public property.
export default defineNuxtConfig({
runtimeConfig: {
public: {
recaptchaSiteKey: 'default value' // will be also exposed to the client-side
}
}
}
Notice the PUBLIC part in the env var:
NUXT_PUBLIC_RECAPTCHA_SITE_KEY=SOMETHING DYNAMIC
This is very strange because we can't access process.env in Nuxt 3
In the Nuxt 3, we are invited to use the runtime config, but this is not always convenient, because the Nuxt application context is required.
But in a situation where we have some plain library, and we don’t want to wrap it in plugins nor composables functions, declaring global variables through vite / webpack is best:
// nuxt.config.ts
export default defineNuxtConfig({
vite: {
define: {
MY_API_URL: JSON.stringify(process.env.MY_API_URL)
}
}
})
And then you can use in any file without dancing with a tambourine:
// some-file.ts
console.log('global var:', MY_API_URL) // replaced by vite/webpack in real value

NG8001: 'mat-table' is not a known element:

I am trying to adapt the following
Example
which works fine. But in my Angular 11 application I ma getting:
error NG8001: 'mat-table' is not a known element
I am using the exact same code that I have placed inside of the shared module. In the shared module I have added the following:
import { MatTableModule } from '#angular/material/table';
#NgModule({
imports: [
MatTableModule
],
...
exports: [
MatTableModule
]
Still, it's not working. Any adea?
Thanks

How do I register component globally in Quasar?

I have a component which I'll be using in every page of my web-app. To simplify my work how do I register this component globally? I used nuxt once and it was so easy by npm #nuxtjs/global-components. What is process with Quasar? Thank you!
You can create a boot file with all your global components, e.g. global-components.js
There you need to import your components and apply them to Vue:
import Vue from 'vue'
import MyComponent from '../component/MyComponent.vue'
Vue.component('my-component', MyComponent)
Lastly you need to call your boot file in quasar.conf.js
boot: ["global-components"]
More info
In Quasar 2:
import { boot } from 'quasar/wrappers'
import MyComponent from '../components/MyComponent.vue'
export default boot(async ({ app }) => {
app.component('my-component', MyComponent)
})
I use this solution and it helps us to dynamically register component
Create a file in src/boot folder for example i created register-my-component.js and white this code:
// src/boot/register-my-component.js
import upperFirst from "lodash/upperFirst";
import camelCase from "lodash/camelCase";
export default ({ app }) => {
const requireComponent = require.context(
"src/components",
true,
/[A-Z-_]\w+\.(vue)$/
);
requireComponent.keys().forEach((fileName) => {
const componentConfig = requireComponent(fileName);
const componentName = upperFirst(
camelCase(
fileName
.split("/")
.pop()
.replace(/\.\w+$/, "")
)
);
app.component(componentName, componentConfig.default || componentConfig);
});
};
Now register this boot file in quasar.conf.js. you can find it in the root directory
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://quasar.dev/quasar-cli/boot-files
boot: [ ..., "register-my-component" ],
Now you don't need to import and register components anymore (NOTE: as you can see only components in src/component register automatically. So if you write your component in other paths you need to import and register that)

Exclude files from Cypress.io Coverage Report

Hi Im using cypress coverage report but I have a class which houses all touch device specific functionality and as I'm running the tests on my Mac, they never run. Is there any way to exclude this class?
you might want to check cypress coverage readme:
...
"nyc": {
"include": [...],
"exclude": [...]
}
...
If this doesn't work:
"nyc": {
"exclude": [...]
}
Then add one more property like this:
"nyc": {
"exclude": [...],
"excludeAfterRemap": true
}
On cypress version 10, what worked for me is to create a .nycrc.json file which contains
{
"exclude": [...],
}

Webpack rebuild is slow using webpack-dev-middleware when building stylus

I'm using webpack 2, with the webpack-dev-middleware
{
test: /\.styl$/,
use: [
'style-loader',
'css-loader',
{
loader: 'stylus-loader',
options: {
use: [nib()],
},
},
]
},
{
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$/,
use: [ {
loader: 'file-loader',
options: {
publicPath: '/dist/'
}
} ]
}
Relevant server code:
let compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
publicPath: ('/dist/')
}));
On the initial build (either using webpack from the console, or on first running my server) the whole process takes ~2000ms. Changing .js files doesn't take long at all (<200ms), but changing stylus files takes a very long time (>90s). If I make a change to the stylus then manually trigger a rebuild with webpack it's really quick, but ideally I'd like the watch to do its magic and for my css to be reloaded in place quickly...
Any ideas why the rebuild is taking such a long with stylus, or how I can debug the issue?

Resources