How to Load CSS files from within Typescript files


#1

How can I read a CSS file relative to one of my ts files and use DOM.injectStyle?

I kind of write a decorator for that:

export function injectCss(value: string): any {
  return function (target: Function) {

    let container = Container.instance;

    let loader: Loader = <Loader>container.get(Loader);

    let css_id = 'inject_css_' + target.name;

    loader.loadText(value).then(css => {
      DOM.injectStyles(css, null, null, css_id);
    });

    target.prototype.injectedCssId = css_id;

    return target;

  };
}

it works fine when addressing an npm module CSS

@injectCss('npm_package/build/test.css')
export class SomeServiceClass{
}

but not when using a relative path

@injectCss('../../my_resource_folder/test.css')
export class SomeServiceClass{
}

Is there any workaround?


#2
import {Origin} from 'aurelia-metadata';
import {relativeToFile} from 'aurelia-path';

const myModuleId = Origin.get(this.constructor).moduleId;
const absolutePath = relativetoFile('../../my_resource_folder/test.css', myModuleId);

Got the idea from here:


#3

The above code is for within component.

Looks like I need to delay the Origin.get in annotation to get it work.

function some(value) {
  return function(target) {
    setTimeout(() => {
      const moduleId = Origin.get(target).moduleId;
      console.log('moduleId: ' + moduleId); // only work after delay
    });

    return target;
  };
}

#4

I am to test the solution, I’ll let you know the result :+1:


#5

It is still undefined.

I guess moduleId is for routes and not a plain typescript class, right? Besides, I need the path of the file in the bundle and it might be different than its absolute path in the file system.


#6

Weired, setTimeout worked for me.

moduleId is the module path of any class known to the loader (requirejs/systemjs/webpack).


#7

My absolutePath = relativetoFile is not talking about the file system, is about the moduleId in view of aurelia Loader.

Aurelia uses relativetoFile func to get the moduleId before load it.

I should write moduleId = relativetoFile.


#8

Curious to know did you find a working solution?


#9

it did not work with moduleId as it is always undefined, however after talking with @jods4 on gitter, and using absolute path the problems sounds to be solved, I test it with fusebox and now I am trying to test with webpack and requireJS, to assure that it will work with either of them.


#10

not yet, only fusebox-aurelia-loader, works fine with what @jods4 suggested. about setTimeout, I am not sure maybe in your case an instance is created and moduleId becomes valid, not sure about life cycle in js, but in my case I didn’t get event one running with moduleId not being undefined. :weary:


#11

I guess you are right, I was testing annotation on component, not a service class. For service, you want to delay it until instantiated.


#12

And another point to mention, components are Aurelia stuff, while services are not, they are plain typescript or to be precise javascript, they might not have moduleId at all; I’ll test it, however.


#13

css tutorial list:

java tutorial
https://javacodegeeks.net/