How to rewrite urls of images in vendor CSS files using Grunt - relative-path

I am trying to move frontend dependencies out of the version control system. A combination of Bower.io and Grunt should be able to do this.
A problem however occurs that I am yet unable to solve with bundling multiple vendor libraries. For example assume I have the following directory structure where the components directory is the directory that Bower.io saves the dependencies in:
├── assets
└── components
├── bootstrap
│   ├── img
│   │   └── glyhs.gif
│   └── less
│   └── bootstrap.css
└── jquery-ui
├── css
│   └── style.css
└── images
├── next.gif
└── prev.gif
Now assume I want to bundle both jQuery's style.css and Bootstrap' bootstrap.css. I will save this bundled file in assets/bundled.css.
However in this file the references to the original images (../images/next.gif and ../img/glyhs.gif) are incorrect. They will have to be rewritten in order to work (so ../images/next.gif => ../components/jquery-ui/images/next.gif). I believe(d) this rewriting of URLs is something Grunt should be able to do. But I can not seem to get this to work using the cssmin/less/copy tasks. For example the following Grunt setup (only moving 1 file) fails to work:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
less: {
options: {
compile: false,
relativeUrls: true
},
bootstrap: {
src: 'components/bootstrap/less/bootstrap.less',
dest: 'assets/bootstrap.css'
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.registerTask('dist-css', ['less']);
};
Either:
Have I misconfigured Grunt or done something wrong?
Or is the workflow I am describing simply not the right one and should I use another one instead.
Thanks!

You probably wat to take a look at this grunt package https://github.com/Ideame/grunt-css-urls.
This package seems to be intended to solve exactly your problem.
Edit: after looking at this plugin I didn't like the idea of rewriting my markup in order to make my build process smoother. So I ended up writing my own tiny function which does the rewrite for me.
I use grunt's concat plugin for bundling my css files. Good thing about this plugin is that it suports file processing function before concatenation. Now my gruntfile looks like this:
grunt.initConfig({
concat: {
options: {
separator: '\n',
process: function (src, filepath) {
var cssPatt = new RegExp('app(\/.*\/).*\.css$');
//filter out everithing except css files
var file = cssPatt.exec(filepath);
if (file) {
var urlPatt = /url\(\'(.*)\'\)/g;
console.log('In file: ' + filepath);
//replace every url(...) with its absolute path
return src.replace(urlPatt, function (match, p1) {
console.log(' * ' + match + ' -> ' + 'url(\'' + file[1] + p1 + '\')');
return 'url(\'' + file[1] + p1 + '\')';
});
}
return src;
}
},
}

Just for reference: there is now a solution readily available. I posted this same issue to the CleanCss grunt plugin, and they have accepted it and published this behaviour in their new 1.1 release.
You can find the issue on the GitHub tracker here: https://github.com/GoalSmashers/clean-css/issues/129
This library makes it possible to either use absolute rewriting (from a root directory) or alter relative image paths based on a new output directory. Look for the --root or --ouput directives.
Thanks for the tips and answers people!

You'll want to do some search/replace on your dist css file to generate the correct relative paths. There are a number of grunt plugins that can do this for you, personally I prefer grunt-replace. Set up your non compressed assets with variables and then produce a dist css with the URLs dynamically generated.. So:
body {
background:url(##IMG_PATH/background.jpg);
}
Becomes this in dist:
body {
background:url(path/to/background.jpg);
}
Hope this helps.

Related

How to tell Vite to only build a specific component in library mode?

I have a Vue project that is able to load other Vue components bundled as .mjs files. I want to develop all those pluggable components inside a repository but instead of distributing all pluggable components in a single build I want to tell Vite which component to build. If that works I don't need to think about dealing with a Monorepo, Multirepo or something else.
After creating the library project I thought about organizing each plugin into a separate folder in the src directory
.
└── src
├── textWithBlueBackground
| ├── index.ts ( importing "TextWithBlueBackground" and exporting as "Renderer" )
| └── TextWithBlueBackground.vue
└── textWithRedBackground
├── index.ts ( importing "TextWithRedBackground" and exporting as "Renderer" )
└── TextWithRedBackground.vue
The problem is that I need to switch to library mode but I don't know what to pass in there
build: {
lib: {
entry: resolve(__dirname, "./src/index.ts"), // this is wrong
name: "Renderer",
fileName: "renderer",
},
rollupOptions: {
external: ["vue"],
output: {
globals: {
vue: "Vue",
},
},
},
},
After fixing that... Is it possible to tell Vite ( via CLI flag ) to only build a specific sub directory? E.g.
vite build ./src/{folderName}
If that's not possible I could create an index.ts in src
import { Renderer as TextWithBlueBackground } from "./textWithBlueBackground";
import { Renderer as TextWithRedBackground } from "./textWithRedBackground";
export { TextWithBlueBackground, TextWithRedBackground }
but how can I tell Vite to only build a specific component then?
The generated .mjs file should only contain the desired component, preferably as "Renderer" but I think the component name should be fine too.

Separate built jar and dependency jars

The application plugin copies the start scripts into 'bin', and copies the built jar and all dependencies into 'lib' (see here). How can I separate the dependency jars and the built jar. I would like to have the build jar in the root folder and change the classpath correspondingly. Tried the change "applicationDistribution" property with include/exclude but this does not work.
I'm able to do:
tasks.installDist {
from("$buildDir/libs") {
include("myLib*.jar")
}
doLast {
delete(fileTree("$buildDir/install/${project.name}/lib") {
include("myLib*.jar")
})
}
}
But this only works for installDist and does no reflect to distZip. How can I move the a jar from the 'lib' folder so that it will work for installDist, distZip and changes the classspath?
Classpath could probably be changed in tasks.startScripts, but therefor the jar should move correctly.
I'm using the Gradle Kotlin DSL.
Desired output would be something like this, where myBuilt.jar is moved from lib to root:
myProgram/
├── lib/
│ ├── lib1.jar
│ ├── lib2.jar
│ ├── ...
├── myProgram.bat
└── myBuilt.jar
Found a solution. I used eachFile (which I was not aware of before) an changed the destination directory:
distributions {
main {
contents {
eachFile {
if (sourceName.matches( Regex("myLib.*\\.jar"))) {
relativePath = RelativePath(true,
*relativePath.parent.replaceLastName(sourceName).segments)
}
}
}
}
}
The classpath for the start scripts has to be changed manually because CreateStartScript hard-coded the classpaths and appends "lib/" (see here).
var jarFileName = ""; // is filled in tasks.jar with archiveFileName
tasks.startScripts {
doLast {
val windowsScriptContent = windowsScript.readText().replace("%APP_HOME%\\lib\\$jarFileName",
"%APP_HOME%\\$jarFileName")
windowsScript.writeText(windowsScriptContent)
}
}
Alternative would be to make a runnable jar: insert classpath into manifest and modify starting script template.

Go to definition not working on my project (vue & sass file) [visual-studio-code]

I am disappointed on two points by developing a Nuxt project on vscode.
On vscode my jsconfig.js is the default one :
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["./*"],
"#/*": ["./*"],
"~~/*": ["./*"],
"##/*": ["./*"]
}
},
"exclude": ["node_modules", ".nuxt", "dist"]
}
It's working on vue file for autocompletion to import some components for example (with ctrl+space)
But impossible to go to definition next with cmd+click. I do not understand why and this is really annoying.
I can't post image (need 10 reputation), but here is my import on vue file (with no definition found for ...)
import PldFooter from '#/components/Footer';
Other point, I use sass files on assests folder. Compilation working well but I cannot access by cmd+click to the file from node_modules. Here is an example of import :
#import "~bulma/sass/base/helpers.sass";
==> No definition found for helpers.sass
Thank you for your help,
Ben.
Have you opened multiple folders (projects) in a window?
I'm not sure whether your issue the same as me. I got an issue "Go to Definition not working" in Visual Studio Code when I opened multiples folders (projects) and I resolved.
I have used the plugin Vetur to support the .vue file.
There are 2 ways which work well:
Open only one project in a window
You can open multiple projects in a window but the project you want to "Go to Definition" works well which must be the first project in the folder tree in the EXPLORER tab.
It seems the plugin Vetur picks up the first project in multiple projects to be the root folder.
My file tsconfig.json
{
...
"compilerOptions": {
"baseUrl": "./",
"paths": {
"#/*": ["src/*"],
}
},
"exclude": ["node_modules", "dist"]
...
}
Reference:
https://github.com/vuejs/vetur/issues/423#issuecomment-405415204
I apologize if my answer which cannot help you.
According to the Vetur setup guide:
If you are using Webpack's alias or TypeScript's path mapping to resolve components, you need to update Vetur's tsconfig.json or jsconfig.json
For example:
└── src
├── components
│ ├── a.vue
│ └── b.vue
├── containers
│ └── index.vue
├── index.js
└── jsconfig.json
jsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"components/*": [
"src/components/*"
]
}
}
}
index.vue
import a from 'components/a.vue'
import b from 'components/b.vue'
It solved the problem in my case.

How to keep pages with .html suffix in eleventy (static site gen) output?

I have an existing oldschool, pure html static site I want to retrofit with an SSG, and I chose eleventy.
The site's structure is as such:
+ index.html
+ somepage.html
+ otherpage.html
As described on https://www.11ty.dev/docs/permalinks/#cool-uris-dont-change, eleventy will create:
+ index.html
+ somepage/index.html
+ otherpage/index.html
I don't want to change the (un)cool URIs I already have :-)
I understand I can add a .htaccess rewrite on the server to rewrite the URLs.
But isn't it possible to configure eleventy so it keeps the exact structure of the old site? I'd think so, but didn't find it in the docs.
This has been answered by pdehaan on https://github.com/11ty/eleventy/issues/913 with a link to https://github.com/pdehaan/11ty-dynamic-permalink-test/
.eleventy.js
module.exports = (eleventyConfig) => {
return {
dir: {
input: "src",
output: "www"
}
};
};
src/pages/pages.11tydata.json
{
"permalink": "{{ page.fileSlug }}.html"
}
This is the source directory structure
src/
└── pages/
├── index.html
├── otherpage.html
├── pages.11tydata.json
└── somepage.html

Sylius Theming - Override web/bundles/syliusweb

I'm trying to override the file:
web/bundles/syliusweb/css/backend.css
Every tutorial I see on theming or overriding shows how to do this for src bundles, for example located in: src/bundles/bundleHere/css/fileHere.css
So far, I've got a theme folder for my theme within app/themes. I've imported a new yml config file for my theme, which reads:
sylius_theme:
sources:
filesystem: ~
I have a composer.json within my theme, which reads:
{
"name": "vendor/my-theme",
"type": "sylius-theme",
"description": "My custom theme.",
"extra": {
"my-theme": {
"description": "My custom theme."
}
}
}
This was enough to get the theme to show up on the 'theme' dropdown in the 'channels' section of the admin panel. I selected my theme, so I assume it's being used.
I've tried overriding web/bundles/syliusweb/css/backend.css, but am having trouble doing it. My changes simply aren't showing, even after dumping assetic. I've also tried clearing the server-side cache. Here are the two locations I've tried for my override:
.
└── MyTheme
├── composer.json
└── public
   └── css
      └── backend.css
.
└── MyTheme
├── composer.json
└── public
   └── SyliusWeb
      └── css
      └── backend.css
I'm not sure how to reference the web bundles, or if there's another step that I'm missing even though I saw and activated my theme. I tried to follow the documentation on theming, but only src bundles were referenced, and some of the instructions didn't have enough information to verify I'd followed them correctly.
UPDATE
I've realized that the same css file also exists where I normally find (and have been able to override) bundle files: src/Sylius/Bundle/WebBundle/Resources/public/css/backend.css
I've tried overriding this the same way I normally would:
.
└── MyTheme
└── SyliusWebBundle
└── public
   └── css
      └── backend.css
I've cleared the cache and dumped Assetic after this, but it also hasn't worked, and I don't see my changes being applied.
  
php bin/console sylius:theme:assets:install