Polymer treats relative URLs as relative to main document.
Polymer 3 provides a [[importPath]] value for relative URLs.
LitElement does not provide this helper.
What is the best way to handle relative paths in LitElement using Polymer CLI build process ?
Polymer needed [[importPath]] due to using HTML imports.
Lit uses ES6 modules, so you can get the current path with import.meta.url.
As there is a built in browser mechanism to access the URL Lit doesn't provide its own (which is core design principle of Lit), but there is a way to shim it - throw and catch an Error and the stack property will include the current file. I don't recommend it though as the browser versions that support modules but not import.meta are extremely obscure.
Related
I found MS DOC about Css in razor. But it isn't work with Scss file.
I resolve this problem by creating two files: css and scss. And use sass --watch. But I need write this every time, when creating new component.
Unfortunately SASS is not supported for CSS Isolation feature of Blazor. At least, not at this moment.
In our project, we use CSS Isolation for the CSS component isolation feature, but we use SASS files to manage our theme, for style we want accros the application.
That being said, if you really need some SASS for an unique component, you totally can, by adding for example a wrapper with a specified id, and use this id in your scss file, with a dedicated name for it, for example MyComponent.scss.
In addition, I've found this article, but I preferred to not use it because it is a bit heavy to setup, but up to you: https://joren-thijs.medium.com/how-to-add-scss-support-to-blazor-cd2a62995441
You can use AspNetCore.SassCompiler which supports both normal and isolated scss. I believe it has a watch mode when using Blazor Server, WASM is not supported yet.
It can also do minification with source mapping.
We have an Angular 8 single page web app deployed on the customer server. They set one of the CSP directive to: default-src 'self'. We build the Angular app using ng build --prod like any other Angular applications. After deploying, we get this error:
main-es2015.47b2dcf92b39651610c0.js:1 Refused to apply inline style because it violates the following Content Security Policy directive: "default-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
Look into the html code on the browser, I see something like this:
As you can see, Angular actually use tag <style> to serve the css (please correct me if I'm wrong). This violates the CSP directive mentioned in the question.
After searching around, I think Angular/React is quite bad at handling this issue, those frameworks are not built with CSP in mind. You can check out Angular github page, there is an open issue for this. Now I'm searching for a solution to overcome this, of course changing CSP policy is not an option because the customers don't want to.
How can I tell Angular not to use tag <style> in production to serve css? I think to make it works we need to set Angular in a way that it will load the css files, and then use styles in those files instead of injecting <style> into html which causes CSP issue.
Edit 1: Our project is using scss.
Edit 2: After searching around, I have found out that Angular will inject your component's styles into the DOM by using <style> element. As shown here:
Now I have an idea, because for each compinent's style will be injeced into the DOM through <style> element, we can prevent this from happening by bundling all component's style .scss file into a single style.scss file. From the image above you can see that we always have an empty <style> element, so if this works, we will endup with only one <style> element and a <link> element that link to our global style scss file. We can have multiple way to remove that empty <style> element before the page got rendered by the browser.
Now I'm stuck at configuring custom webpack to make this happen. We cant use ng eject to get the webpack.config.js file since Angular CLI 6. I've been using Angular CLI 8 so the only way for me to add custom configuration into Webpack is to use custom-webpack npm. I cant find a good config file that has the same output as my desire, please help if you know how to config webpack to bundle all component's styles scss files in Angular into a global scss file.
I think this can be an acceptable answer for my question:
First of all, my recommendation is stay away from using styleUrls. Angular will inject styles of your component into the DOM using <style> element. Secondly, if it's possible, you should know / ask for the CSP policy on the deployment server/environment. What I have been doing to resolve the issue (my project is reletively small with just a couple dozen of components):
Copy (one by one) relative link of components, put them into angular.json, in styles attribute. This is because Angular will bundle all styles in this attribute as a single css/scss file. I copy one by one because the css/scss file was designed to work with Angular View Encapsulation in the first place. Gathering all of them into one place might introduct unexpected issue, this will break the UI. Whenever copy a component style and put into styles, I check if the UI breaks because of that. This will help me narrow down the root cause if such issue happens.
For each component, after copy its component style file's relative path into styles, I remove styleUrls in #Component. This prevents Angular from injecting <style> into the DOM.
Caveats:
Gathering all styles into one single file and load them at once might cause performance issue. Luckily my company project is relatively small.
Now you need to document the new way of making styling work in your project.
I have built my app with React Boilerplate, and have been surprised to find all my CSS modules are not generating CSS as I thought, but the CSS is instead generated from JS and embedded in the header of the page. The image below shows just some of the many, many style elements that appear in my header after the page has loaded.
For development, I can see this making sense for HMR etc. However, for a production build, it is not what I would expect.
I would think the most performant build (ie, best) would be a static CSS file alongside the js. In fact, in our production build there is a lot of stutter as the site loads and applies styles to the elements in a staggered manner.
It seems straight-forward to build a static CSS file, so why isn't it the default (especially for RBP, whose major claim is that it is production-ready). After 5 mins of searching I found https://github.com/webpack-contrib/mini-css-extract-plugin, which seems to do exactly what I want.
Is there a benefit to dynamically adding the CSS in the document header as pictured? Is there anything we would lose if we built a static CSS document instead?
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)
},
]
}
I'm using webpack to generate the appropriate files for a npm package which will host a few react components. They have some CSS attached, which references some fonts and icons.
When using the file loader, these assets are mis-referenced using their absolute paths (i.e. fonts/my-font.woff) in the main app which are missing.
Is there a way to fix this and make my main app look for the right files? I'd rather fix the package itself than doing things like copying the assets like someone has mentioned as I may not have full control of the main app.
Well, I'm going to preface this by saying that including fonts in a component is usually a bad idea since the main app likely has its own style/branding/etc that you'll be fighting with.
That said, if the fonts are something like icons you could base64 encode them and inline that in the CSS. There are several Webpack encoder plugins to do that.
You also mentioned icons, I would try to convert these to SVG and serve them up inside the code. You could also base64 encode the PNGs into your CSS as a fallback.
The benefits, to this approach:
Eliminating HTTP requests in the parent app
Parent app always has the latest (non-cached) icons/fonts when you update your package
You don't have to worry about paths, packaging external files, etc
Cons I can think of:
You're increasing script sizes significantly
You lose some caching benefits
If you're not the copyright owner of the icons/fonts, this may violate TOS