How do I include the same Web Component dependency in multiple Components without "duplicate registry" error - web-component

I am making a lib similar to Polymer Material. I have individual files I use rollup to create a single ESM, CJS, and UMD file. The ESM file is the main in the package.json. I have a situation like this
Header
Icon-Button
Icon-Button
The icon button Uses Mustache so I need to include it using the rollup-plugin-node-resolve. I then import the library in Header and create a UMD file that is imported into my we app like this...
// Pug
script(src="/ui-components/header/dist/index.umd.js")
script(src="/ui-components/icon-button/dist/index.umd.js")
// Express
// #me/icon-button
// #me/header
const uiPath = path.join(__dirname, './node_modules/#me');
app.use('/ui-components', express.static(uiPath));
I get the following in the browser console on load...
Failed to execute 'define' on 'CustomElementRegistry': the name "me-icon-button" has already been used with this registry
How do libraries handle this? I thought about removing the resolve plugin for mustache and assuming it is included globally. However, it seems pretty onerous to make everyone find a way to import mustache into window and not something most libraries do. I could also do something like this question suggests...
customElements.get("me-icon-button")||customElements.define("me-icon-button", IconButton, {...});
But having that multiple times in my code does not seem right either.
So How do I include multiple web components that reference other similar components?

Related

Is there a way to use CSS modules without adding .module. extension in NextJS?

I am trying to configure a NextJS project. I want to use CSS modules. However, I don't want to add *.module.* extension to file names and thus adding it to import paths, since it seems to me as excessive.
I found in css modules documentation that they didn't use module extension.
I tried to customize webpack configuration with loaders within next.config. Without any luck.
So, I am wondering if there is any way to be able to use just someName.css in NextJS. Then I could import it to my component just like this: import style from './someName.css'

Conditional stylesheet in Nuxt SSR depending on a store value

I've been surfing StackOverflow and the Nuxt documentation, but I cannot get my head around this one.
So, I need to do RTL. My project is in Nuxt and we use SCSS. I'm setting the htmlAttrs to dir="rtl" conditionally depending on a store getter that tells me if the language is RTL or not. The requirement for this specific task is that a RTL stylesheet should be imported conditionally from the server side also if the country is RTL, so that it overrides the main.scss file.
Now, in nuxtServerInit(), I cannot set the stylesheet in the head, because the route will not direct me to the file, and, most importantly, Webpack won't compile it, as it's outside the regular flow of the application and not imported by main.scss, which is the stylesheet the Nuxt config is pointing to, and which contains all other styles. I realize that I could use a class and use it conditionally in components, but that is not the requirement. The nuxt.config.js file, in the relevant part, looks like this:
css: [
'#/assets/styles/main.scss'
]
There I obviously don't have access to the store.
What I said I tried was this:
if (isRTL) {
service.addEntryToArray('link', {
rel: 'stylesheet',
type: 'text/css',
href: '../assets/styles/main.rtl.scss'
});
}
(We use a service to add things to the head)
I understand that was naive on my part, because Webpack has no say there, so there is no transpilation, and there is no actual asset, which means the route is just wrong, and even if it were right, the browser would not be able to read it.
Any ideas on how this could be achieved at a non-component level? This needs to be part of the Webpack flow, has to be added server-side, and needs to be an import --I cannot just import it regularly and use just a class (again, I'm not stubborn, I'm working on a project, and this is a requirement by the client).
If you need more information, I'll update the post, but I don't know what else to provide.

Using styled-components with imported CSS files from a node_module

I am using styled-components in a React project. So far it has been working fine, but now I want to use the react-datepicker package, which requires its styles to be imported the following way:
import "react-datepicker/dist/react-datepicker.css";
However, importing the file causes an error that says "You may need an appropriate loader to handle this file type". I know I could fix this by creating a handler for .css files, but I thought I could avoid that by using Styled Components.
My question is, is there a way to handle these type of imports with styled components? I've been loooking online for hours and can't seem to find a way.
I ended up just forking the project and changing it to use styled-components instead of needing to import the styles.

CSS modules and rollup - generating separate CSS files ("themes") with same hashes

I'm using CSS Modules (Sass) with rollup on a component library project, which is working well. Each component ends up with a dist folder containing a single JS bundle file, and a corresponding CSS file with the scoped CSS classes so consumers of the component don't have to worry about CSS class name conflicts. All they do is include the JS bundle and the CSS file and everything is great. Yay CSS Modules.
The problem I'm now facing is that some components really need separate "themes" - ideally, separate CSS files, one per theme. So consumers can continue as they've been doing: including the JS bundle, but now choosing which CSS file to include to pick a theme.
I'm not sure how to get this going with CSS modules & rollup, and whether this is even the sort of approach others are taking. From what I can see, rollup always handles bundling things together, whereas I want separate CSS files, all of which get their classes renamed identically during the build phase. That way, if within my JS I refer to styles.myclass, if myclass had gotten renamed to scoped-myclass by CSS modules for the original CSS file, for a second CSS file it would also get the same name.
This would keep consumption of the component extremely simple - just a matter of including a different CSS file.
Any suggestions?
Awfully late, but let me answer this 3 years on. So what I ended up doing was totally detaching the CSS generation step from rollup and relying on the Sass CLI to handle that portion of the build process. It felt a bit klutzy, but I remember it wasn't awfully hard to do and solved the problem I outlined above. I don't believe there was a plain rollup solution at the time, nor do I think there's one today.
However... in my case the whole approach was kinda mistaken. This certainly won't be everyone's scenario, but let me spell it all out because hey it may be useful and it definitely wasn't obvious to me at the time.
This was for an in-house shared component library, where each component and its corresponding CSS was a separate npm package stored in our Artifactory. When it grew, plenty of internal references popped up, e.g. multiple components would reference the Button component, and over time they'd reference different versions of the Buttons component - each of which needed its own properly scoped CSS, unique to that package-version.
So what I found was that by doing it this way - having the CSS generated as part of the npm package dist files - I had to write an additional layer for the consumer applications that would parse their node_modules/ folder for our own internal components and combine all the different CSS files, such as the multiple versions of buttons. e.g. the main application would directly import buttons v1.0.0 in its package.json file, but the Dialog component (also included in the package.json) could include buttons 2.0.0 as its own dependency. For every version of the package, there was a uniquely scoped version of the CSS - so the consuming application HAD to include every version otherwise the styling would be borked.
So all in all, it ended up being way more complex that I wanted. I thought I could make it easier & better with the separate generated themed CSS files as part of the package dist, but it didn't end up that way. If I could revisit that project today, I'd re-examine a solution used by Material UI and others which I kinda poo-poo'd at the time: automatic injection of the CSS into the page by the component JS, rather than generating standalone CSS files which required extra work by the consumer applications to gather up and add to the final webpage. Frankly, now I regard it as the "least crap". There are definite downsides to the injection approach (extra work done on every page render for everyone! Yikes!), but there's no doubt in my mind it hugely simplifies the job of the consumer applications. It's a balancing act, but in 20-20 hindsight I'd lean towards the injection approach. With that, scoping & theming is a different and much simpler problem.
If I got you right, consider looking at SCSS plugin: rollup-plugin-scss. It captures all spare .css files imported in the components, and then processes them through underlying node-sass. The catch is, it seems like you can write a custom callback function that'd handle your CSSs differently based on conditions you throw in.
Based on the example from the plugin's page:
import scss from 'rollup-plugin-scss'
...
export default {
input: 'src/index.tsx',
output: [...],
plugins: [
...
output: function (styles, styleNodes) {
// replace this with conditioned outputs as needed:
writeFileSync('bundle1.css', styles)
writeFileSync('bundle2.css', styles)
},
]
}

problem with import bootstrap theme to ruby on rails app

I can't seem to import this bootstrap theme to my rails application.
https://github.com/puikinsh/sufee-admin-dashboard
I am trying to import this template for two days but no luck. It could be easy, but I don´t know what I´m doing wrong :(
I receive this error:
Undefined variable: "$border-color".
Undefined mixin ....
So I have got a problem with variables and mixins at the first time. I tried another template and it works, so I really don´t know what to try next.
Any hint or idea about how to solve this problem would be really appreciated.
Thanks
Porting a template into your Rails application is not hard if you break it down into several imprortant steps:
Import styles. From what I can see, your template is using sass along with plain css style files. You can pick one of those and copy the files into your /app/assets/stylesheets folder and importing them in your application.sass. The Undefined variable: "$border-color". points you towards missing variables.scss, which contains all the color variables for your template.
See if your template is using any third-party libraries or frameworks. In this particular example, there is a list of them in the repo's "Built With" section of the readme. Go through every single one of them and find gem versions of those libraries and add them to your Gemfile.
Copy non third-party Javascript files into your app/assets/javascripts. Require them in pagedown.coffee.erb along with third-party modules. Be sure to keep non third-party code below other modules to preserve functionality of code that relies on those modules.
Trim HTML templates into views. Figure out what part of your layout should be preserved for every page and put it into your layout view, break down the rest into controller-specific views.
There can be a lot of problems, but in general, just try to analyze the errors being thrown and solve them one by one.

Resources