I was wondering if anyone could help me with this.
I have a project where I am creating multiple html pages for different sites. Each of these sites shares a common assets folder (fonts, css, js etc) my directory layout is as follows:
|-- project
| |--assets
| | |—-css
| | |—-images
| | |—-fonts
| | |—-js
| |--site-1
| | |—-index.html
| |--site-2
| | |—-index.html
| |--site-3
| | |—-index.html
What I would like to achieve is the following:
• A 'dist' folder that contains:
|-- dist
| |--site-1
| | |—-index.html
| | |—-style.min.css
| | |—-image1.jpg
| | |—-image2.jpg
| | |—-image3.jpg etc...
| | |—-scripts.min.js
| | |—-font1.otf
| | |—-font2.otf etc...
| |--site-2
| | |—-index.html
| | |—-style.min.css
| | |—-image1.jpg
| | |—-image2.jpg
| | |—-image3.jpg etc...
| | |—-scripts.min.js
| | |—-font1.otf
| | |—-font2.otf etc...
| |--site-3
| | |—-index.html
| | |—-style.min.css
| | |—-image1.jpg
| | |—-image2.jpg
| | |—-image3.jpg etc...
| | |—-scripts.min.js
| | |—-font1.otf
| | |—-font2.otf etc...
Just to explain the desired result:
• each site is 'flattened' within a directory, so that all of the assets, images, js, css, fonts are on the same level as the index.html file. (a requirement of the 3rd party that needs these)
• The corresponding links in each of the .html, .css & .js are updated the reflect the above.
• At times there might be more or less than just 3 'site' folders - so it would be great if I could 'loop' through and detect a folder name convention (??) - just a nice have if anyone smarter than me knows how to do this with a grunt task.
I have been trying the grunt-rebase task to make this work. It sounds like it is what I need, however I am really struggling with the documentation to make it work, along with a lack of experience with grunt tasks.
Any help would be great. If you need any more info please let me know.
EDIT - here is my grunt.js file - I have removed unneeded tasks and other bumpf for clarity.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
copy: {
main: {
files: [
{expand: true, cwd: 'project/', src: ['**/*'], dest: 'dist/', filter: 'isFile'}
]
}
},
rebase: {
scoped: {
files: [{
//css ref's
expand: true,
cwd: 'dist/assets/css/',
src: '*.css',
dest: 'dist/site-1/',
reference: '../assets/images/',
scopes: {
url: {
'../images/': '',
'../fonts/': ''
}
}
}, {
//html ref's
expand: true,
cwd: 'dist/site-1/',
src: '**/*.html',
dest: 'dist/site-1/',
reference: true,
scopes: {
url: {
'../assets/images/': ''
},
img: {
'../assets/images/': ''
},
link: {
'../assets/css/': ''
},
script: {
'../assets/js/': ''
}
}
}, {
//images
expand: true,
cwd: 'dist/assets/images/',
src: '**/*',
dest: 'dist/site-1/'
}, {
//fonts
expand: true,
cwd: 'dist/assets/fonts/',
src: '**/*',
dest: 'dist/site-1/'
},
{
//js
expand: true,
cwd: 'dist/assets/js/',
src: '*.js',
dest: 'dist/site-1/'
}]
}
}
});
//1 - make copy of entire prod directory to 'dist folder'
//2 - rebase task
//3 - TODO - delete dist/assets folder (not needed after rebase)
grunt.registerTask('Create Exported Project', [
'copy',
'rebase'
]);
};
The above rebase task works....but only for one folder that i hard code into the 'dest' field for each scope (the 'site-1' folder).
I was hoping for some flexibility to be able to loop through all folders that match a condition (maybe the string - 'site-').
Related
Given the json
{ "games": [
{
"id":1,
"files": [ "foo.mp4" ]
},
{
"id":2,
"files": [ "foo.ogv", "bar.ogv" ]
},
{
"id":3,
"files": [ "bar.ogv" ]
}
]}
and the command
jq -r '.games[] | select(.files[] | contains("ogv"))' foo.json, json outputs an element once for every time it matches ogv in the subelement array. How do I get jq to output each matching element only once?
Using any would be more efficient than relying on unique. E.g.
jq -r '.games[] | select(any(.files[]; test("ogv")))'
jq -r '[.games[] | select(.files[] | contains("ogv"))] | unique | .[]' foo.json
or, since what I really want is just the id,
jq -r '[.games[] | select(.files[] | contains("ogv")) | .id] | unique | .[]' foo.json
src directory:
dir1
|-- 1.js
|-- 2.js
`-- sub-dir1
`-- 1.js
dest directory:
min
`-- dir1
|-- 1.min.js
|-- 2.min.js
`-- sub-dir1
`-- 1.min.js
My code snippet:
uglify: {
t2: {
options: {
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */'
},
files: [{
expand: true,
src: ['dir1/**/*.js'],
dest: 'min',
rename: function (dst, src) {
return dst + '/' + src.replace('.js', '.min.js');
}
}]
}
}
But I want to skip source directory under destination directory, desired structure is:
min
|-- 1.min.js
|-- 2.min.js
`-- sub-dir1
`-- 1.min.js
There's a couple of ways to achieve this. Solution A (below) is the simplest and most commonly used.
Solution A
When building the files object dynamically you can utilize the cwd property. The description of the cwd property in the docs reads:
cwd All src matches are relative to (but don't include) this path.
Change your files property to the following:
// ...
files: [{
expand: true,
cwd: 'dir1/', // <-- Add this.
src: '**/*.js', // <-- Change your src glob to this.
dest: 'min',
rename: function (dst, src) {
return dst + '/' + src.replace('.js', '.min.js');
}
}]
// ...
Solution B
Another way, (without utilizing the cwd property), is to change your rename method to the following instead:
// ...
rename: function (dst, src) {
src = src.split('/');
src.shift();
src = src.join('/');
return dst + '/' + src.replace('.js', '.min.js');
}
// ...
The src = src.split('/'); part utilizes the String split() method with the / separator to split the src path into an array of individual path items.
The src.shift(); part utilizes the Array shift() method to remove the first element from the array (e.g. dir1).
The src = src.join('/') part utilizes the Array join() method with the / separator to form the new path as a String.
I'm working with grunt-contrib-copy. I have this file tree:
`-- src
`-- model
|-- a4
| `-- public
| |-- css
| |-- img
| `-- js
|-- posters
| `-- public
| |-- css
| |-- img
| `-- js
`-- prints
`-- public
|-- css
|-- img
`-- js
I would like to copy the files in
src/model/**/public/img to dist/images/{1}/ where {1} is the folder name (a4, posters, prints... dynamic folders that are bound to change too), so:
src/model/a4/public/img/file.png -> dist/images/a4/file.png
Is there a way to specify that with grunt-contrib-copy (maybe the rename function?) or do I have to iterate manually over the files?
Right now this is what I have:
grunt.registerTask 'images-generate', ->
gruntCopyFiles.images = {
expand: true,
cwd: './src/model/',
src: ["**/public/img/*.png", "**/public/img/*.jpg"],
dest: "./dist/images/"
}
But this copies src/model/a4/public/img/file.png to dist/images/a4/public/img/file.png which is not what I want.
Any suggestion? Thanks!
Is there a way to specify that with grunt-contrib-copy (maybe the rename function?) or do I have to iterate manually over the files?
Utilizing the rename function is the way to achieve this. Glob patterns alone cannot meet your requirement, nor can the flatten option.
Something like the following also copies any subfolders which may potentially reside inside the source img folders:
gruntCopyFiles.images = {
expand: true,
cwd: 'src/model',
dest: 'dist/images',
src: '**/public/img/**/*.{png,jpg,gif}',
rename: function(dest, src) {
var items = src.split('/'),
baseIndex = items.indexOf('img') + 1,
subPath = items.slice(baseIndex, items.length).join('/');
return [dest, items[0], subPath].join('/');
}
}
Example:
src/model/a4/public/img/file.png --> dist/images/a4/file.png
src/model/a4/public/img/quux/file.jpg --> dist/images/a4/quux/file.jpg
Looks like you can use flatten to get stripped-down destination paths:
gruntCopyFiles.images = {
flatten: true,
expand: true,
cwd: './src/model/',
src: ["**/public/img/*.png", "**/public/img/*.jpg"],
dest: "./dist/images/"
}
From the docs:
flatten Remove all path parts from generated dest paths.
My Chrome app contains three .nexe files for arm, x86-32 and 64-bit processors. When I install this app from Chrome web store, the size of downloaded package is the same as the size of the app containing all .nexe files. Is it possible to optimize this network traffic?
My .nmf file bundled in the app looks like this:
{
"program": {
"arm": { "url": "arm.nexe" },
"x86-32": { "url": "x86_32.nexe" },
"x86-64": { "url": "x86_64.nexe" }
}
}
Thanks
Yes, you can add a platform specific section to your manifest.json. Then the packages will only download the components that are specified for that CPU architecture.
There is documentation for that feature here: https://developer.chrome.com/native-client/devguide/distributing#reducing-the-size-of-the-user-download-package
And there is an example in the SDK as well: examples/tutorial/multi_platform
To summarize the documentation above:
First create a _platform_specific directory in your App package. For each architecture, create a subdirectory with that name:
|-- my_app_directory/
| |-- manifest.json
| |-- my_app.html
| |-- my_module.nmf
| +-- css/
| +-- images/
| +-- scripts/
| |-- _platform_specific/
| | |-- x86-64/
| | | |-- my_module_x86_64.nexe
| | |-- x86-32/
| | | |-- my_module_x86_32.nexe
| | |-- arm/
| | | |-- my_module_arm.nexe
| | |-- all/
| | | |-- my_module_x86_64.nexe
| | | |-- my_module_x86_64.nexe
| | | |-- my_module_x86_32.nexe
Then in the manifest.json file, specify the location of these directories:
...
"platforms": [
{
"nacl_arch": "x86-64",
"sub_package_path": "_platform_specific/x86-64/"
},
{
"nacl_arch": "x86-32",
"sub_package_path": "_platform_specific/x86-32/"
},
{
"nacl_arch": "arm",
"sub_package_path": "_platform_specific/arm/"
},
{
"sub_package_path": "_platform_specific/all/"
}
]
You'll want your .nmf to point to the location of these nexes. The SDK build system has an option to do all of this for you automatically, I'd suggest using it.
I have the following Gruntfile:
module.exports = function(grunt) {
//Project configuration.
grunt.initConfig({
copy: {
main: {
files: [
{
expand: true,
cwd: "source/",
src: ["!**/*.less", "**"],
dest: "compiled/"
},
],
},
},
});
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.registerTask("default", ["copy"]);
};
My goal is to have it copy everything from the source folder to the compiled folder. For example, if this was my file structure before running Grunt...
[root]
- Gruntfile.js
- source
\- test.txt
\- sample.html
\- file.less
- compiled
...I am expecting to get...
[root]
- Gruntfile.js
- source
\- test.txt
\- sample.html
\- file.less
- compiled
\- test.txt
\- sample.html
...but instead I get:
[root]
- Gruntfile.js
- source
\- test.txt
\- sample.html
\- file.less
- compiled
\- test.txt
\- sample.html
\- file.less
I thought that setting the source to ["!**/*.less", "**"] would fix this, but that isn't the case. Why doesn't this work (what is it actually targeting) and how can I fix this?
Negating patterns should be placed after matching patterns since they negate the previous match:
copy: {
main: {
files: [
{
expand: true,
cwd: "source/",
src: ["**", "!**/*.less"],
dest: "compiled/"
},
],
},
}
See the globbing patterns docs for examples, like:
// All files in alpha order, but with bar.js at the end.
{src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: ...}
By placing "**" after your negating pattern, you're overriding it.