I´m using single-spa library (v 5.8.2) with multiple angular projects. When i try to import ngx-quill (library which imports another library (quill.js)), the single spa library replaces the default import url with localhost:9000 (the url root loads into).
I have followed the single-spa instructions to modify the scss url, images and other own elements, but remember that in this case, the import call is made from an external library, which should not be modified.
I have also tried to insert my own interceptor in which, if it detects that specific url, it is replaced by the one I want, but since this call is not REST, it does not go through that one and I cannot modify it.
Is it possible to make single-spa by default modify the routes so that they access the corresponding node_modules?
Thank you!.
the single spa library replaces the default import url
single-spa does not do anything at build time and is only used in the browser.
What is actually happening is that ng-quill likely makes use of relative references to external assets. This could be in JavaScript (import "./styles.css") or in CSS (#import("./styles.css") but in either case, this means that in the browser the app will try to resolve those. But those URLs being relative means that they're relative to the origin that loaded the asset, which is the root config. That is why you're seeing those URLs.
Is it possible to make single-spa by default modify the routes so that they access the corresponding node_modules?
The answer to this is no, because single-spa is not what is causing this. You need to instead configure your build tool (Webpack is what Angular uses I believe) and handle the processing of those URLs. The single-spa-angular
Angular community has documented them here https://single-spa.js.org/docs/ecosystem-angular/#styles
Related
In my workplace I've been told by my supervisor to use autoloaders instead of using many import statements since it's slow! First of all, based on my research there are no performance benefits of doing so and secondly(I'm using js modules, and we are not talking about bundles), I can't think of any good reasons for doing such thing.
The way my imports work now are:
Imagine we import a.mjs like so ->
import '/js/components/a.mjs'
The route /js/ is a rule that redirects to my root of static js files, so I don't even need to use relative paths.
Is it bad practice? If there is something that I'm missing anything please tell me; I've done my research and didn't find any reasons to use autoloaders with js modules.
An actual example for you to see:
Flask route rule:
#app.route('/js/<path:filename>')
def js(filename):
return send_from_directory(Path(app.root_path).parent.absolute().joinpath("static\\js"), filename)
and in my js files:
import {View} from "/js/common.mjs";
import Spinner from "/js/components/spinner.mjs";
import RecommendedTripsSlider from "/js/components/recommended-trips-slider.mjs";
import TripsSlider from "/js/components/trips-slider.mjs";
import Blogs from "/js/components/blogs.mjs";
Thank you for your time. I appreciate it.
From the JavaScript Modules Guide on MDN :
Modules are only executed once, even if they have been referenced in multiple <script> tags.
This can be verified in the spec under section 16.2.1.5.2 Evaluate.
Evaluate creates and returns a Promise which resolves when the module has finished evaluating. This Promise is stored in the [[TopLevelCapability]] field of the [[CycleRoot]] for the component. Future invocations of Evaluate on any module in the component return the same Promise.
The first time the browser needs a module, it is hoisted, loaded, cached and executed. Additional import statements in future scripts will reference the pre-evaluated module from memory. No additional HTTP requests need to be made. No additional execution needs to happen.
On subsequent page views, the locally cached version of the module will be used, assuming your server's caching policy is configured appropriately, or you've implemented caching with a service-worker. In fact, you can even preload any specific modules that you might need ahead of time.
Performance-wise, as long as your app isn't importing hundreds of modules you should be fine. At that point you should probably look into bundling related components together with tree shaking. However, monolithic app bundles should be avoided as they obliterate the benefits gained from using modules since one small change to a single component means your users now have to re-fetch the entire app. Keeping your components split up means that user agents only download the parts needed to display the content on the page they're on and nothing more.
One reason you might want to use a module loader/bundler would be if you were installing dependencies through a package manager like npm. Then you would need a way to resolve the named imports to their actual file paths. But that process can easily be handled without a build step by using import-maps.
<script type="importmap">
{
"imports": {
"moment": "/node_modules/moment/src/moment.js",
"yourlib": "/lib/yourlib.js"
}
}
</script>
Unfortunately, this feature is not available in all browsers yet but. This already works in Chromium based browsers, has recently been implemented in Firefox (slated for release in v102) and support for other browsers can be polyfilled with es-module-shims.
This is the future of native module resolution. Implementing an autoloader into your project now would be a step backwards.
I would like to create an absolute link to files (images, downloads, ...) in my static directory, so during development the link would be http://localhost/myimage.jpg and once deployed it should be https://www.example.com/myimage.jpg.
Is there an easy way (e.g. an environment variable etc.) to reference the current domain name in Gatsby?
I would like to achieve this behavior without changing any config files.
A relative link is not an option in my case. The reason is that I am using the plugin gatsby-plugin-react-intl which modifies all relative links by adding the locale in front of it, meaning, the above mentioned link would automatically turn into https://www.example.com/en/myimage.jpg instead of https://www.example.com/myimage.jpg.
The default behavior is what you described. Using the static folder, a structure like /static/myimage.jpg will be referenced as https://somedomain.com/myimage.jpg.
The same approach applies to PDF or any static asset you wish to make available.
Following that, a structure like: /static/images/myimage.jpg will become https://somedomain.com/images/myimage.jpg.
Keep in mind that the static folder structure is "cloned" inside the public one once the site is built so everything inside will become public. /static becomes the root path once cloned.
I know that this is the default behavior. The problem is, that I'm
using react-intl (or more specifically, gatsby-plugin-react-intl),
which modifies all these paths by adding the locale in front of it,
e.g. <img src='/myimage.jpg' /> becomes <img src='/en/myimage.jpg />.
Using gatsby-image for all purposes is not possible, because it
doesn't work with SVGs etc. I haven't figured out how to stop the
plugin from doing this and I thought knowing how to refer to a your
own domain in js (or react) would be something worth knowing.
Well, there are multiple ways to point to your current domain. From the window.location.origin (check caveats of using window or global objects in SSR) to the default location props exposed by Gatsby (because its extension from #reach/router, from React). Note that location props will be only available in top-level components (pages) but you can drill down or use it as you wish, as any other property.
In addition, the gatsby-plugin-react-intl plugin exposes some methods that provide the current language information, useful to build your own static path to the asset. Using:
const { locale } = useIntl();
Will give you the current locale. You can use it to build your own asset like:
<img src={`/${locale}/images/myimage.jpg`} />
This path will work whether you are in local development or in your hosted project domain, because of the relativity. If you still want to use the full domain, you can use the previously explained location (React-based approach) or the window.location (JavaScript-based approach).
Regarding the automatic modification of static assets and paths, I'm afraid it's the default plugin's behavior and I haven't found any way or exposed method to change it otherwise.
So, I have a NextJS application and the way I have been building links is through component. For eg: <Link href="/my-page"><a>My page</a></Link>. I have built the whole app with this pattern for However, when I did an export to generate a static site, it created the out folder with pages with .html extension. This is now a problem, since, say a link might be pointing to /my-page but the actual page is /my-page.html. What's the right way of handling this issue? Does NextJS allows us to do anything in this situation or do I need to go back and code all my tags using /my-page.html links?
Thanks.
The default in next.js for static generation is to map this code:
/pages/p1.tsx
to this file:
/p1.html
The problem with that is that a link to /p1 will work when you use the next server, and will fail when you're serving static files.
If you enable this, in next.config.js:
module.exports = {trailingSlash: true,}
Then you'll get a different file:
/p1/index.html
And on most generic web servers (Apache out of the box, for example), you get this behavior:
/p1 - redirects to /p1/
/p1/ - serves /p1/index.html
/p1/index.html - serves /p1/index.html
So I think module.exports = {trailingSlash: true,} gets you the behavior you're expecting.
(#jdaz's link to the other answer is definitely useful for this, but that question was very specifically about configuring .htaccess, so I'm repeating a similar answer here)
I created a angular library with angular 9 cli. What I noticed: I can only include modules by loading the whole library:
Of course this makes no sense in a real world application. I want to be able to load each module individually. What am I doing wrong? Why can't he find the image component under #devmonkeys/mark6/image
I linked the repository because I don't know exactly what it is. I think this makes more sense than posting the code of 6 possible files here.
What I mean exactly: #angular/material for example, each component has its own path to avoid loading the whole library into the app during build. https://material.angular.io/components/button/api as an component namend MatButton. to import it we must use: {MatButtonModule} from '#angular/material/button'; i also want this, because it makes no sense to load the whole libary in my code only because i want 1 component.
There is a main app.js file which has import {Route} from "./router". Router - a class that depending on the the current url of page, will create an instance of this page handler. For example, for page /home/accountPage - router will create a handler in this way: return new AccountPageHandler(params). It turns out that in the router imported all handlers of all pages (and them so much). And when I do System.import ( 'js/app.js') I will loaded all the scripts, including and unnecessary - because they are imported into the router, and the router imported in app.js.
How can I make so that does not import all at once, and only that I want to use? I am sure that this problem is already getting up earlier for many developers, but how to fix it - I have no idea because I faced with for this first time.
P.S.
My javascript is generated from the typescript (if suddenly this affects the options for solving the problem).
Without seeng the actual code, my guess is SystemJS imports all of your scripts because you import all handlers of all pages. What you could do (if your router supports promises and async loading of page handlers). Is to use System.import('specific_page_handler.js') to import only the page handler needed right now.
But depending on the size of you app, and on the size of separate chunks you can lazy-load, just creating a minified bundle, setting a long cache expiration, and loading all at once can be just fine. Possibly small gains with added complexity.