Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic CSS urls #30

Open
reinaldoarrosi opened this issue Nov 6, 2017 · 4 comments
Open

Dynamic CSS urls #30

reinaldoarrosi opened this issue Nov 6, 2017 · 4 comments

Comments

@reinaldoarrosi
Copy link

Is there a way to make CSS urls dynamic, i.e. make css urls be resolved in runtime?

When using webpack with css and style loaders it does this by transforming css url from this format background-image: url("images/my_img.png") to this background-image: url("' + webpack_require('images/my_img.png') + '"). This way, when css is inlined into the js file, the funcion gets called and the url is resolved at runtime.

My use-case is: I'm working with an application that needs to support virtual directories but I don't know beforehand the names of these virtual directories. My only way of knowing the absolute path for any given file is during runtime.

I've already tried using postcss to change the "url" in css files in a way that would make them dynamic, but when scssify inlines the css into js it calls JSON.stringify, which escapes quotes and "undoes" the string concatenation that would make urls dynamic.

@cody-greene
Copy link
Owner

I suppose you could use TOKEN_STRINGS in the css source and replace them at runtime.

// .thing { background-image: url('VIRTUAL_DIR/images/my_img.png') }
let template = require('./foo.scss')

// .thing { background-image: url('abcdef/images/my_img.png') }
let css = template.replace(/VIRTUAL_DIR/g, 'abcdef')

// ... inject ...

@reinaldoarrosi
Copy link
Author

Yes, that's what I've ended up doing. But since I'm using the autoInject option I don't have a place where I can call the replace method.

What I did was create a fork of scssify and added an option called postProcess which is a function that receives the generated css and then calls replace to change these TOKEN_STRINGS.

@cody-greene
Copy link
Owner

Now I'm confused. The process you're describing does replacement at build-time?

But if you want to modify the style urls based on some application state, in the browser, (run-time) you'll have to turn autoinject off and do it yourself like so:

// See: scssify/lib/browser.js
const scssify = require('scssify')

const template = require('./main.scss')

let css = template.replace(/VIRTUAL_DIR/g, 'abcdef')

// Inject a <style> tag to the document head
scssify.createStyle(css)

@reinaldoarrosi
Copy link
Author

It replaces at build time for a function call.

So this:
.thing { background-image: url("/path/to/img.png"); }

Turns into this:
.thing { background-image: url("' + appPath.resolve('/path/to/img.png') + '"); }

This process is exactly what webpack does, but instead of appPath.resolve webpack uses webpack_require.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants