Open homestar9 opened 1 year ago
These should be resolved in coldbox-elixir@^4.0.4
. Could you pull that version down @homestar9 and confirm?
Thanks @jclausen. I have a few observations/notes:
1. Relative paths in .scss URLs appears to be fixed! Wohoo! The final url does follow the weird "../../includes/..." pattern, but my guess is it's because the current version of resolve-url-loader throws an error if it can't find the files. Regardless, it's working!
2. Copying images from submodules to the same module works!
// in /modules_app/mymodule/elixir-module.js
mix.copy( "resources/assets/images", "includes/images" ); // works as expected!
3. Images in tracked sub modules are being copied to the /includes/images folder in the app root and the submodule simultaneously when referenced in .scss files, which is odd.
Let me know if you want help replicating the issue, but the TLDR is to create a simple tracked submodule, put an image in the /modules_app/resources/assets/images/ folder, and then reference it in a .scss file in /modules_app/resources/assets/sass/app.scss. You will see when you npm run dev
the image will be copied to two different places.
// .scss file in modules_app/mymodule/resources/assets/sass/
background-image: url( "../../images/module-logo.png" ); <-- image copied to this submodule AND root for some reason
4. sourceMappingUrls
now have the absolute path from the root, but this causes Chrome Dev tools to break:
/*# sourceMappingURL=modules_app\login\includes\css\app.css.map*/
should be
/*# sourceMappingURL=app.css.map*/
Here's what it looks like in the Chrome dev console:
5. Referencing an image in the root of the project from a tracked submodule will cause the resulting css link to point to the wrong place. Lets say you have a logo in the /resources/assets/images/ folder and you want to reference it from a tracked submodule scss file located in /modules_app/mymodule/resources/assets/sass/app.scss: This:
background-image: url( "../../../../../../resources/assets/images/logo.png" );
Becomes this:
background-image: url(../../includes/images/logo.png);
Which breaks the link.
OK. I will take a look at that sourcemap issue today.
I'm not sure about #5. It kind of breaks the idea of module encapsulation for a module to reference an asset from the root. Either way, mix.modules
will normalize that referenced root file in to the moduleroot/includes/images
directory - which is the expected behavior.
So, I guess I'm confused by these two statements, which seem to conflict:
put an image in the /modules_app/resources/assets/images/ folder, and then reference it in a .scss file in /modules_app/resources/assets/sass/app.scss. You will see when you npm run dev the image will be copied to two different places.
Referencing an image in the root of the project from a tracked submodule will cause the resulting css link to point to the wrong place.
I'm not sure about 5. It kind of breaks the idea of module encapsulation for a module to reference an asset from the root
I know what you mean @jclausen . However, sometimes tracked submodules will need to reference global assets, like a logo, color scheme, fonts, theme, etc.
Imagine a PetStore app scenario where you have Dog and Cat tracked submodules. The Dog and Cat modules would have their encapsulated functionality but may also depend on global assets like the name of the pet store, a logo, color scheme, etc.
In fact, even the Ortus HMVC API convention breaks encapsulation to some degree. Tracked submodules are created in the API (e.g. /api/v1) to contain the handlers, but all of the models are placed in the root of the app, thus making them global.
On a personal level, I have always looked at tracked submodules in a modules_app
folder as being "extensions" of the root app, whereas non-tracked modules should be treated as isolated/sandboxed dependencies.
That being said, I believe both issues (3) and (5) are separate problems. I will try to clarify my position.
Issue 3 says that images are being duplicated and copied to more than one location. If you put an image in a tracked submodule, it is copied to the includes folder of the submodule (correct behavior) and another copy is placed in the root (incorrect behavior - also breaks encapsulation). Using the Petstore example, if the Cat module uses a picture of Catnip in its .scss file, webpack will copy it to the correct location in the submodule and create a redundant copy in the root (and possibly overwriting another asset if the file names are identical). The diagram I created shows where the assets are copied/duplicated.
Issue 5 says that if a submodule references a global asset, the URL to the global asset is not preserved.
For example, if a Cat module needs to link to a global logo file in the Petstore root ../../../../../../resources/assets/images/logo.png
, webpack will change the final link to ../../includes/images/logo.png
thus breaking the link/reference.
Hopefully this helps! Let me know if you need any assistance troubleshooting or if you want me to put together a test repo.
@jclausen one other thing I noticed related to items 3 & 4 above when using production mode npm run prod
:
When running npm run prod
and you have an image in a tracked submodule, the image is not duplicated, but it is copied to the root /includes/ folder instead of the submodule includes folder.
Example:
/modules_app/modulename/resources/assets/sass/app.scss
links to an image:
/modules_app/modulename/resources/assets/images/module-image.jpg
Execute npm run prod
The image /modules_app/modulename/resources/assets/images/module-image.jpg
is copied to /includes/images/module-image.95822a715e4a785fd795.jpg
The correct location should be: /modules_app/modulename/includes/images/module-image.95822a715e4a785fd795.jpg
Hi @jclausen, thanks for taking the time to assist. I have summarized a list of issues I discovered when working with .scss or .sass files in Elixir V4. We already covered item 1 yesterday on Slack. The rest of the numbered items below may also be related.
1. Relative paths are translated incorrectly when converting SASS to CSS.
Will become
The relative path should be preserved in the final output.
2. Nested/tracked submodule images are not copied to the right folder when using
mix.modules()
If you create a tracked module that has its own .scss files which reference images, the images are copied to the project's root /includes/images/ folder instead of the tracked module's /modules_app/modulename/includes/images/ folder. Here's an example: In the above example, the
login
module has its own .scss file and image which should be copied to the /includes/ folder within the submodule. However, today, if you runmix.modules()
on the submodule, the image will be copied to the project root and the resulting CSS will point to the wrong place. The resulting css file should preserve the relative path like this:Side-note (nice-to-have): I know the convention for ColdBox is to output images in the /includes/images/ folder. However, I see a lot of developers using a folder called /img/ for images which is a nice abbreviation. It would be nice if we could configure Elixir to customize the resulting image output folder just in case we want to use a different naming scheme.
3. Source maps have the wrong path applied to them.
When processing .scss files, the resulting source map address contain the wrong path, which makes it hard for browsers to find them. Here's an example of a source
sourceMappingUrl
that was generated for a .scss file:/*# sourceMappingURL=includes\css\app.css.map*/
It should be:/*# sourceMappingURL=app.css.map*/
Typically source maps reside in the same folder as the minified file so there's no need for an absolute path.4. Using
mix.copy()
withinelixir-module.js
needs absolute paths from root.If you want to copy assets from a tracked module from the resources to the includes folder within that module, you must specify the absolute path from the root of the app, otherwise, Elixir won't copy the resources to the right place. Example:
Currently, the above code will copy both the images from
/resources/assets/images
and/modules_app/modulename/resources/assets/images
to the root/includes/images
folder. The expected behavior would be to copy the/modules_app/modulename/resources/assets/images
to/modules_app/modulename/includes/
folder. The workaround for this issue is to feed the absolute path tomix.copy()
like this: