Open skylarmb opened 3 years ago
@skylarmb I've fixed this bug in an improved version of this package: style-implant
as a workaround I created my own rollup plugin that is essentially a fixed version of this package that also includes a number of inproments:
window
or document
)head
. Simply create a meta or style tag in your head <style id='style-inject-insert-before'></style>
and all styles will be injected directly above that element, allowing you to control the order of injected styles vs other global stylesheets.plugins/style-inject/index.js
:
import path from 'path';
const styleInjectPath = path
.resolve('plugins/inject-styles/styleInject')
.replace(/[\\/]+/g, '/');
// This function is a codegen/codemod function that adds code to each
// module during compilation. This is how rollup plugins generally work
export default function styleInject() {
return `
import styleInject from '${styleInjectPath}';
styleInject(stylesheet);
`;
}
plugins/style-inject/styleInject.js
:
export default function styleInject(css) {
if (!css || typeof document === 'undefined') return; // don't error out if using SSR
if (window._DISABLE_STYLE_INJECT === false) return; // allow turning off injection
var INSERT_BEFORE_ID = 'style-inject-insert-before'; // id of element in head where styles should be injected before
var head = document.head || document.getElementsByTagName('head')[0];
// an empty style tag that is inserted at the top of the head and which all
// further styles are inserted before. This fixes the reverse insertion issue
// reported in https://github.com/egoist/style-inject/issues/23
var elementToInsertBefore = document.getElementById(INSERT_BEFORE_ID);
// if this is the first injected style and there is no user-defined element to insert before,
// we must create the insert-before element that we will use for all further injections
if (elementToInsertBefore == null) {
elementToInsertBefore = document.createElement('style');
elementToInsertBefore.id = INSERT_BEFORE_ID; // if there is already stuff in the head, put this first
if (head.firstChild) {
head.insertBefore(elementToInsertBefore, head.firstChild);
} else {
// if the head is empty, just insert this
head.appendChild(elementToInsertBefore);
}
}
var style = document.createElement('style');
style.type = 'text/css';
head.insertBefore(style, elementToInsertBefore);
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
style-inject
is used byrollup-plugin-postcss
and many other packages. When used in these packages there is an issue withinsertAt
behavior.Given the following imports
Without
insertAt: 'top'
the resulting injected styles areWith
insertAt: 'top'
the resulting injected styles areThis is incorrect as a's styles were imported after b, so should override the styles from b naturally by being imported second.
What this plugin really needs in an option to preserve the order of stylesheets relative to each other but still insert them at the beginning of the head