-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
bundling less 3.0.1 with web-pack, targeting web-worker. #3178
Comments
I'm using Less in a Web Worker as well, and also ran into issues with the new version. I'm not using any plugins or any of the browser functionality (automatically processing stylesheets in the DOM etc.) in my app, so for my case I was able to solve it as follows: // in my worker
import Less from 'less/lib/less';
const less = Less();
less.PluginLoader = function() {};
less.render(/* your input */).then(result => console.log(result.css)) However, I was also running into Webpack build errors because of some inline // in my webpack config
import ReplacePlugin from 'webpack-plugin-replace';
const config = {
// ...
plugins: [
// ...
new ReplacePlugin({
exclude: /.*/,
include: /node_modules\/less/,
values: {
"require('promise')": 'Promise'
}
}),
// ...
]
// ...
}; If you do actually need Less plugins and are directly or indirectly importing e.g. Not exactly pretty solutions, I know! 😅 |
Thanks for your help! Cheers! |
My pleasure, but I have since found out, after some more poking and prodding, that I was basically completely wrong! My code/build "worked" for other reasons, and ReplacePlugin does not seem to do any work on the code before it reaches Webpack's processing/resolving logic (I don't know if this is even possible within Webpack), so importing
This isn't the type of dynamic PS In addition to the above, I wrongly assumed that ReplacePlugin's |
TO ANYONE ELSE READING THIS: this is NOT a recommended way of doing things, especially in production!You almost may as well fork Less.js to modify it for your own purposes at this point, which may actually be a better solution. I am only posting this for the sake of completeness. Hopefully we can find a way to officially support running Less in a web worker soon. @dasdeck I was hacking around some more just now, and found a way to make it work, albeit in a very dirty way by most standards. I even added the pi plugin from the docs, which seems to work as well (it loads, and calling Basically, it loads the precompiled version from // using raw-loader here to import the file as a string
import LessRaw from 'raw-loader!less/dist/less';
const PiPlugin = {
install: function(less, pluginManager, functions) {
functions.add('pi', function() {
return less.dimension(Math.PI);
});
}
};
const location = {
href: '',
protocol: 'https'
};
const document = {
getElementsByTagName: () => [{ dataset: {} }],
location
};
const window = {
document,
location,
// less options that get picked up during Less initialization
less: {
onReady: false,
plugins: [
PiPlugin
]
}
};
// put it all together
const Less = new Function('window', 'document', `${LessRaw}\n return window.less;`);
const less = Less(window, document);
// worker code
self.onmessage = function({ data }) {
// `data` being Less code that you got from whatever posted the message to your worker
less.render(data)
.then(result => self.postMessage(result.css))
.catch(error => console.warn('Error in worker', error));
}; |
@joepvl To handle the problems surrounding the What you then need to do is replace the unbound variable reference to less.js/lib/less-browser/plugin-loader.js Lines 9 to 13 in efa6eb5
— with a reference to an AMD compliant loader that is capable of working inside web workers. |
Thanks for the response, @rjgotten! I didn't know you could use a loader to inject things to be globally available to imported modules. Alternatively, I guess That leaves us with the less.js/lib/less/environment/abstract-plugin-loader.js Lines 64 to 69 in efa6eb5
If this is indeed the case, then I think it's worth considering removing it, because nobody may ever use it to begin with. IMO people could just be expected to take care of it within their plugins themselves — after all, the docs don't advertise require magically being available within plugin code, right? But maybe I'm missing something here with respect to the original intent of the code, and/or how this is supposed to work.
I'll probably test these things in the near future, if only for the satisfaction of it. 😉 @dasdeck how did you get on? |
You might not even need a dedicated loader to inject globals into the worker source here. self.window = require( "window-shim" );
self.document = require( "document-shim" );
var less = require( "less" ); That will create |
TL;DR - The in-scope require override exists in 3.0 for backwards-compatibility reasons. See: less/less-meta#17
So, the over-ride of
So, I did months of work to essentially bridge the gap. The goal was to let Probably I could have made life easier on myself by just killing the previous Incidentally, this is kind of what Node.js does anyway. That is, a So that's the long and short. In an effort to be backwards compatible, and not have two COMPLETELY DIFFERENT types of Less plugins, that's why that exists. Moving forward, the best option is to: A. Write or compile & distribute your plugins as a single file. If you want to see the history / discussion on the two plugin systems and how they were unified, you can go here: less/less-meta#17 |
@matthew-dean thanks for taking the time to explain, I appreciate it! |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Here is a browserified bundle that can be used in the browser directly: |
Hi!
I can not get less 3.0.1 to bundle properly into my web worker code.
Less 2 was working flawlessly with the same setup.
When I import less like this:
I get
less.js:78 Uncaught ReferenceError: window is not defined
in the browser console, which kind of makes sense, as the bundle uses thedist
version for the browser but a worker has nowindow
.since the imports are static, I see no way of shimming the window away.
in the old version we did it like this:
which would set a window object.
This bundle, however, throws an error:
which seems to be related to this particular line of code:
./browser/plugin-loader.js:9
here is my web-pack conf.
Cheers!
JM
The text was updated successfully, but these errors were encountered: