Import dynamic text file into svelte? - import

I have about 50 text files containing SVG paths that need to be parsed in ParseSvg.svelte.
+page.svelte
<script>
import ParseSvg from "../components/widgets/ParseSVG.svelte";
let hex = "#c412dd";
let src = 'w1815'
</script>
<ParseSvg {hex} {src} />
ParseSVG.svelte
Hardcoded works perfectly:
import src from "$lib/svg/w1815.svg?raw";
I've tried:
export let src;
function getSVGUrl(src) {
return new URL( /* #vite-ignore */ `/src/lib/svg/${src}.svg?raw`, import.meta.url).href;
}
const s = getSVGUrl(src)
console.log(s)
Console Log Produces:
file:///src/lib/svg/w1815.svg
Trying this:
const s2 = import(s);
Produces this error:
The above dynamic import cannot be analyzed by Vite.
Please point me in the right direction.

When constructing a URL and just using that, this code will not be processed by Vite at all. For that to work you have to manually include your static assets or (in the case of SvelteKit) put them in the /static directory which is already included.
When doing this you also will not have access to the file contents directly (?raw will do nothing), so if you want to access the contents you first have to load the file, e.g. using fetch.
If you want to use a dynamic import instead, you have to follow certain rules. Vite uses a rollup plugin to support this, which comes with various limitations. One of them is that paths have to be relative, another is that a file extension has to be specified (please see the documentation for the full list so you do not miss anything).
As an example given these files:
+page.svelte
svg.svelte
svg-1.svg
svg-2.svg
The page could use the svg.svelte component to reference one of the SVGs via its suffix:
<script>
import Svg from './svg.svelte';
</script>
<Svg source="1" />
<Svg source="2" />
Then the component could dynamically import the given file and simply output it as HTML:
<script>
export let source;
</script>
{#await import(`./svg-${source}.svg?raw`) then { default: svg }}
<span>{#html svg}</span>
{/await}
(For further processing, the file should be imported in an async function in the script.)

Related

how to load external css file with lit

Although lit provide some ways to deal with css, however I have some existing css files which I would like to use in some components, what should I do?
I have read this page https://lit.dev/docs/components/styles/ but now helpful with existing css files.
My recommendation is: Don't.
The ShadyCSS polyfill doesn't support external style sheets.
External styles can cause a flash-of-unstyled-content (FOUC) while they load.
The URL in the href attribute is relative to the main document. This is okay if you're building an app and your asset URLs are well-known, but avoid using external style sheets when building a reusable element.
External css files should only be loaded in your html file (index.html most probably).
The css should be bundled with your element.
An alternative for reusabilty would be to export shared styles and import them in your styles properties as follows:
static styles: CSSResult[] = [
// language=CSS
AnimatedStyles,
ShadowStyles,
css`
[...]`;
And import from a shared file.
export const ShadowStyles = css`
[...]
`;
export const AnimatedStyles = css`
[...]
`;
That way, they are also loaded only once.
Modern method: Only work with chromium based browser.
Read more Using CSS module scripts
import styles from './my-styles.css' assert { type: 'css' };
class MyEl extends LitElement {
static styles = [styles];
}
Other solution:
By using vite build tools:
import style from "./style.css?inline";
class MyEl extends LitElement {
static styles = unsafeCSS(style);
}

Dynamically inject content into JSDoc #example

I'm using JSDoc to document my javascript API.
I have an #example where I exhibit a minimized loader script (similar to the Google Analytics script). The loader script loads additional javascript from https://<server>/myProduct/lib/script.js.
My JSDoc documentation is bundled with myProduct, so there are aways /myProduct/lib/script.js and /myProduct/docs/ side-by-side. However, myProduct can be hosted by my customers anywhere, so I don't know what the <server> is.
I would like to be able to use document.location.href to detect current browser URL, and display a working loader script in my #example, so that customer can simply copy & paste a working script from documentation without having to manually edit the <server> part.
My question is: Does JSDoc offer any means to dynamically inject content into #example?
I could just manually edit the JSDoc output and include some custom javascript manually, which replaces <server> with the actual current server on run-time. However, this would be tedious to do every time my documentation updates.
No, JsDoc doesn't provide for injecting external content, and while it is certainly possible to create a JsDoc plugin to include external content during document generation, I don't think this would get you where you need to be.
I think the simplest answer would be to post-process the output of JsDoc to add a simple script, like
<script>
// retrieve the hostname from the current url.
const getServiceHostName = () =>
document.location.href.replace(/http:\/\/([\/]+)\/.+$/, '$1');
// replace the content of the span#service-host with the current hostname.
document.onload = function () {
document.getElementById("service-host").textContent=getServiceHostName();
};
</script>
to your html files just above the </body> tag.
Then, in the example content, insert a <span id="service-host"></span> where you'd like the service hostname to appear.
Another approach might be to take advantage of the fact that JsDoc passes the content attached to the #description tag directly into the html output.
So, this appears to do the expected:
/**
* Hostname: "<span id="service-host">hostname</span>"
*
* <script src="https://code.jquery.com/jquery-3.6.0.min.js"
* integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
* crossorigin="anonymous"></script>
*
* <script>
* $(document).ready(function() {
* $("#service-host").html(document.location.href);
* });
* </script>
*
* #name How-To-Monkey-Patch-JsDoc
*
*/
Note that the content of #example is wrapped in <pre><code>...</code></pre> in the html output which will definitely cause you problems, but it should be easy to post-process the html inline using the code above, by adding some recognizable token (perhaps [[HOSTNAME]]) into the example content and on document load, replace it with the desired value.
Please note also that this approach has the possibility of opening your docs to security issues, which is why I'd use the first solution above.

loading all the import maps from a separate JSON file in Single-SPA?

i am working on a micro-front end application with the help of Single-SPA framework.
i am able to import and make it work by adding the MFE routes directly in index.ejs file.
since we have a lot of MFEs, i don't want to keep them all in index.ejs.
want to keep all the routes in separate JSON file and import then JSON file in to index.ejs file.
so the question is , is there a way we can import JSON file directly in EJS template ??
there are similar questions in stackover flow but all of the answers are pointing to render method which i don't find it on single-spa library ?
step-1 : create a JSON file under src folder (ex: src/local-map.json)
step-2 : remove the JSON map from index.ejs and paste in the created JSON in step-1
step-3: update the index.ejs like below
<% if (isLocal) { %>
<script type="systemjs-importmap" src="./local-map.json"></script>
<% } %>
step-4: add the below code in webpack.config.js or webpack-proxy.config.js
devServer: {
static:'src'
}
that's it :)

How to import .html fragment using es6 syntax in TypeScript

How to import an HTML template from a relative path like this:
import customSelectHtml from "./custom-select.html!text";
TypeScript compiler complains that it cannot find module. I was trying to create an ambient module definition, but it doesn't allow relative paths in module names. I am using SystemJS as a module loader.
I'm not using typescript, but I do use ES6. Might be useful for you.
The way that I solve this is by declaring template strings using ` ` quotes. It works fine for me, I would be happy to know if someone thinks this is a bad habbit.
below a snippet with Angular(-ui-router).
index.js
var indexTemplate = `
<div>
<h1>{{ Index page }}</h1>
</div
`
export {indexTemplate}
config.js
import { indexTemplate } from './index.js'
function config($stateProvider){
$stateProvider.state('index', {
url: '/',
controller: 'indexController',
template: indexTemplate
})
}
For completeness, this assumes indexController is defined elsewhere. Also, this config function is exported to a place where app is defined. But that all is not related to the question.
It is impossible.
Due to the definition of what is module in typescript, and as far as I know in ES6 javascript (import). Module cannot be html. The common approach is to import a javascript module that exports a string containing html, css, whatever. But that is not importing of the file with raw html.
Maybe you want to have a look at html imports also, but that is completely different thing.
You can import it using require syntax
1) Create app.d.ts file and require definition so typescript know this is function. (you don;t need to add any addition library, systemJs support require syntax)
declare function require(params:string): any;
2) Now you can import your html using
var template = require('./custom-select.html!text')
I found it even better because you can use require inline
var directive = {
template: require('./custom-select.html!text'),
scope: {}
}
I don't know about SystemJS, but this is definitely possible with Webpack and the html-loader

How in Sails to access globals in assets?

I am using Sails JS and would like to access globals (sails.config.myGlobals) in my assets, currently in js files.
I would have hoped I there is a similar way like injecting in ejs files. But its not.
Any ideas? Do I have to do a Grunt task for that?
In your config folder create a config file for example MyConfig.js (name doesn't matter). Fill that config with something that you wanted like.
module.exports.myconfig = {
configA: 'this is config A'
}
Use that config in your controller, like.
showconfig: function(req, res){
res.view('viewname', {
config: sails.config.myconfig
});
}
Now in your EJS file that is called, by that example is viewName.ejs at views folder, you can use it like <% config.configA %>, and this is config A would be printed. Also if you want Front End js (in assets folder) able to read that value, just print it in script tag, like this.
<script>
global.configA = '<%= config.configA %>';
</script>
Or if you use front end framework library, it can be placed under some value, service, or factory, not making global variable dirty, so other JS are able to read that value.
I don't think this is possible with Sails.
However, what you can do is setting the variable in a ejs view file to access its value in your js asset file.
// someView.ejs
<script>
myGlobals = '<%= config.myGlobals %>';
</script>