Pude generar una biblioteca de activos y muchas otras bibliotecas que funcionan como módulos federados remotos y como bibliotecas de importación profunda en caso de que no me esté conectando a un control remoto o no esté usando un paquete web en el extremo del consumidor.
El problema ahora es que todos mis activos exportan un módulo, que tiene los datos sin procesar como uri o la cadena que apunta al activo correcto. Por ejemplo: el pájaro.svg se convierte en polvo con su hash más los módulos que se resuelven en el archivo pájaro-[hash].svg.
Lo anterior es excelente para javascript pero no tanto para css. Ahora no puedo reescribir la url() para que apunte a la ruta remota correcta, que sería como:
//since I don't know when the assets will change names I can't refer to it directly. So I would need to first read the string from the bird.js module. Append the publicPath and then rewrite the url. .someClass { background-image: url('/assets/bird.js') } //the above won't work for obvious reasons.Só, la pregunta es ¿cómo puedo solucionar esto? ¿O hay algún cargador para esto? Revisé el cargador de URL de resolución, pero no parece ser lo que necesito.
Ok, resolví este problema pasando datos adicionales como variable a sass-loader. De esa manera, puedo evaluar el nombre real de los archivos y ponerlo como un mapa sass antes y manejarlo desde sass.
//I am using glob to return an object with all the assets. //This can probably be automated better. That would be an easier way. //But this way works for me in all 3 scenarios, node, browser and federated module. //Also has caching ootb for the assets. const assetsPaths = { ...glob.sync('../assets/dist/img/**.node.js').reduce(function (obj, el) { obj['img/' + path.parse(el).name] = '../../assets/dist/' + require(el).default; return obj }, {}), ...glob.sync('../assets/dist/fonts/**.node.js').reduce(function (obj, el) { obj['fonts/' + path.parse(el).name] = '../../assets/dist/' + require(el).default; return obj }, {}) }; //... { loader: 'sass-loader', options: { additionalData: "$assets: '" + assetsMap + "';", sourceMap: true, sassOptions: { outputStyle: "compressed", }, } }, //...también necesita deshabilitar la reescritura de URL
{ loader: 'css-loader', options: { url: false, } },entonces puede usar el mapa de activos en sus archivos sass:
@font-face { font-family: 'Some Font'; src: local('Some Font'); src: url("#{map-get($assets, SomeFont)}"); }Probablemente necesitará tener la configuración de su proyecto como un repositorio mono y también necesitará construir esa biblioteca de activos con dos paquetes.
Uno para el nodo para que pueda usar la ruta de la cadena a sus activos reales al agrupar su sass/lo que sea. Y otro por cargarlo normalmente desde el navegador.
actualizar:
En lugar de hacer todo esto, solo usé el manifiesto generado desde 'webpack-manifest-plugin' para construir el mapa de $assets que se usará en sass.
const assetsManifest = JSON.parse(fs.readFileSync('../assets/dist/manifest.json')); const assetsMapFn = asset => `'${asset[0]}':'${asset[1]}'`; const assetsMap = `( ${Object.entries(assetsManifest).map(assetsMapFn).join(',')} ); `;Si alguien sabe una mejor manera de hacer esto, por favor responda o comente.