-
-
Notifications
You must be signed in to change notification settings - Fork 386
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
Support passthrough dependency request. #944
Comments
Seemingly related but I feel this could be conveniently supported by minicss. Something along the lines of an option to use ExternalModule instead of CSSModule within the plugin |
Yeah like on the Loader Options
|
Yes, let's wait answers and we will decide how best to design/implement it |
Fantastic! Fully willing to contribute on this one as well! |
How will this work during SSR?? @ScriptedAlchemy |
Consumer build would be in charge of last mile. So css loader / mini css would strip the imports out and just leave the local exports. Same way it works today. Just slight differentiation between packaging via final build by consumer |
Update on this. My team took my loader idea mentioned above and added an extra loader before mini css. Then using contextify we are able to inject a require or import() depending on if its esm or cjs. Not sure how we could implement import since im depending on magic comments or non webpack require to prevent it getting extracted again. Bit hacky but it seems to work for the time being while this issue is being investigated |
@ScriptedAlchemy Feel free to send a PR (with any solutions) so we can dicussion on code |
Hello! This is what we wrote on loading the field's css output. I took the mainFields value to construct the css path, since I think that's what this plugin is using to generate the css file. We have a couple checks just for browser targets and modules in order to pass the right fields in. Seems to work for our case, and would love feedback on it! module.exports = function (content) {
const { utils, _compiler: compiler } = this;
if (!compiler.options.output.library && compiler.options.target === "web") {
this.callback(null, content);
return;
}
const mainFields = compiler.options.resolve.mainFields;
const outputPath = (field) =>
utils.contextify(compiler.outputPath, `./${field}.css`);
let result;
if (compiler.options.output.module) {
result = mainFields.map((fieldString) => {
return `import(/* webpackIgnore: true */ '${outputPath(fieldString)}')`;
});
} else {
result = mainFields.map((fieldString) => {
return `__non_webpack_require__('${outputPath(fieldString)}')`;
});
}
result.push(content);
this.callback(null, result.join(";"));
}; |
@alexander-akait any suggestion on how we could implement. I’m happy to send a PR if you have a hint or sample of what/where I should start |
@ScriptedAlchemy Do you have any solution? If yes, let's add the option and feel free to send a PR with code that you have. Exampe above is good, we need the same |
Excellent I'll start tomorrow with my team. I see it as need for emit asset, use mini css loader to handle exports. Then take js and emit it, then inject the require into the file with the css module maps. |
Okay im going to try and factor this into mini-css tomorrow. const AUTO_PUBLIC_PATH = "__mini_css_extract_plugin_public_path_auto__";
const BASE_URI = "webpack://";
const { getOptions, interpolateName } = require("loader-utils");
const path = require("path");
const { normalizePath } = require("./utils");
const handleExports = (exports) => {
const result = exports.default || exports;
return {
content: result.toString(),
locals: result.locals,
};
};
async function pitch(content) {
const options = {};
const callback = this.async();
let { publicPath, module } =
/** @type {Compilation} */
(this._compilation).outputOptions;
let loaderArray = this.request.split("!");
loaderArray.shift();
const nonCircularLoader = loaderArray.join("!");
const result = await this.importModule(
`${this.resourcePath}.webpack[javascript/auto]!=!!!${nonCircularLoader}`
);
const handledResult = handleExports(result);
let loaderResult = [];
const context = options.context || this.rootContext;
const name = options.name || "[contenthash].external.css";
const url = interpolateName(this, name, {
context,
content,
regExp: options.regExp,
});
if (typeof options.emitFile === "undefined" || options.emitFile) {
const assetInfo = {};
if (typeof name === "string") {
let normalizedName = name;
const idx = normalizedName.indexOf("?");
if (idx >= 0) {
normalizedName = normalizedName.substr(0, idx);
}
const isImmutable = /\[([^:\]]+:)?(hash|contenthash)(:[^\]]+)?]/gi.test(
normalizedName
);
if (isImmutable === true) {
assetInfo.immutable = true;
}
}
assetInfo.sourceFilename = normalizePath(
path.relative(this.rootContext, this.resourcePath)
);
console.log(assetInfo);
console.log(url);
this.emitFile(url, handledResult.content, null, assetInfo);
}
if (module) {
loaderResult.push(`import '${url}'`);
loaderResult.push("export default " + JSON.stringify(handledResult.locals));
} else {
loaderResult.push(`require('${url}')`);
loaderResult.push(
"module.exports = " + JSON.stringify(handledResult.locals)
);
}
this.callback(null, loaderResult.join(";"));
}
module.exports = {
default: pitch, ///TODO: actually use loader.pitch instead of loader
}; |
Feature Proposal
Feature Use Case
I want to use webpack to bundle npm packages and component libraries that come with css/scss.
Currently, mini-css treats css resources as side effects. Which makes sense when webpack is the consumer build, but does not make sense if webpack is a library build.
Id like to still process styles, but leave the require statement as an external.
example:
require('./button.scss') -> becomes document.createElement(handleSideEffectDep)
for library builds id like to
require('./button.scss') -> require('./dist/248.css') so that the consumer build manages the side effect and i can ship component libraries that require their own css, but do not handle DOM injection.
Currently you would have to use style-loader which is not optimal. The alternative avaliable is using something like rollup which does not attempt to bundle side effects of a library, instead it treats it like an external once emitted. Then the consumer build is responsible for loading the side effect and its runtime requirements to inject styles.
Current output:
desired output
If i add a very primitive loader to the start of the loader chain, it kind of works (though resolution paths would be incorrect. But that could be fixed.
that would process the file as i need, and still load a require() into the file as a side effect - however this should point to main.css to pair with main.mjs/js
Please paste the results of
npx webpack-cli info
here, and mention other relevant informationThe text was updated successfully, but these errors were encountered: