I'm trying to copy an index.html file to multiple folders. I've been looking on stack overflow and almost found the solution i'm looking for. The loop in my example only copy's the index.html file to the last folder of the folders array. I wonder what i'm overlooking. any ideas?
module.exports = function(grunt){
grunt.initConfig({
copy:{
files:{
flatten:true,
expand: false,
src: [
'scaffold/index.html',
],
dest: "dist/<%= grunt.option('folder') %>/",
filter: 'isFile',
force: true
}
}
})
function copytoFolders() {
var folders = ["300x600", "300x250", "336x280"], folder;
for (folder in folders)
{
grunt.option('folder', folders[folder]);
grunt.task.run('copy');
}
}
grunt.loadNpmTasks('grunt-contrib-copy-force');
grunt.registerTask('copyFol', copytoFolders)
}
Ok i solved it by looking at this post:
stack overflow post
So basically it now returns a file object array and when the default task is called, it executes the object files.
Here is the script that works for me:
module.exports = function(grunt) {
function getFiles() {
var folders = ["300x600", "300x250", "336x280"];
var files = [];
for (var folder in folders) {
files.push({
flatten:true,
expand: true,
src: [
'scaffold/index.html',
],
dest: "dist/" + folders[folder] + "/",
filter: 'isFile'
});
}
return files;
}
grunt.initConfig({
copy: {
core: {
files: getFiles()
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('default', ['copy:core']);
};
Related
I'm struggled with the following and would appreciate any help...!
I try to use Laravel Mix (v5.0.4) and extend it with SVG sprite loader (svg-sprite-loader) to generate SVG sprite. I have the following folder structure:
resources/
images/
image.jpg
sass/
app.scss
svg/
file1.svg
file2.svg
webpack.sprite.js
webpack.mix.js
The content of webpack.mix.js:
const mix = require('laravel-mix');
require('./webpack.sprite');
const toCss = 'public/css';
mix.sass('resources/sass/app.scss', toCss)
.options({
sassOptions: {
outputStyle: 'nested',
}
})
.sprite();
The content of webpack.sprite.js:
const mix = require('laravel-mix');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
const path = require('path');
class Sprite {
dependencies() {
return ['svg-sprite-loader'];
}
webpackPlugins() {
return new SpriteLoaderPlugin({plainSprite: true});
}
webpackRules() {
return {
test: /\.svg$/,
include: path.resolve(__dirname, 'resources', 'svg'),
use: [
{
loader: 'svg-sprite-loader',
options: {
extract: true,
spriteFilename: path.resolve(__dirname, 'resources', 'images') + 'sprite.svg',
runtimeCompat: true
}
},
'svg-transform-loader',
'svgo-loader'
]
};
}
}
mix.extend('sprite', new Sprite());
It does NOTHING in regards sprite, but it generates the CSS from SASS! :( I don't know why... Tried to "debug" it with some console.log() in the extension and it was hit, I saw the log messages in the console. But the sprite wasn't generated.
I also tried to use just hardcoded, relative paths in the extension without path. Didn't help.
Any idea?
Thanks in advance!
I have a feeling this is related to Webpack5's new Asset module.
https://webpack.js.org/guides/asset-modules/
For assets to be written to disk, or possibly primed to be handed off to large plugins you need to now specify asset type and generator to best define a filename for these assets.
webpackRules() {
return {
test: /\.svg$/,
include: path.resolve(__dirname, 'resources', 'svg'),
type: 'asset/resource',
generator: {
'filename': '[name][ext]'
},
use: [
{
loader: 'svg-sprite-loader',
options: {
extract: true,
spriteFilename: path.resolve(__dirname, 'resources', 'images') + 'sprite.svg',
runtimeCompat: true
}
},
'svg-transform-loader',
'svgo-loader'
]
};
}
If still no luck try an alternative plugin:
https://www.npmjs.com/package/webpack-svg-spritely
Alright, one for the ages. The issue is I am trying to merge the structure from multiple sources into a single one. One of my sources is from the template.html which contains the base structure for index.html -source-. I trying to find a solution that replaces html block data from the source -index.html- body tag into the destination -template.html- lastly create a new merged document which outputs to -dest-.
File structure that is as follows:
public
---assets
------template.html
---src
------app.js
------index.html
------main.css
---dist
------merged.html
I am using npm package gulp-replace (but open to other packages).
var gulp = require('gulp');
var htmlreplace = require('gulp-html-replace');
var copycat = require('gulp-copycat');
gulp.task('default', function() {
// create a watch task
gulp.task('default', function() {
gulp.src('assets/template.html')
.pipe(htmlreplace({
'cssInline': {
src: gulp.src('sheetgmail/main.css'),
tpl: '<style>%s</style>'
},
'body': gulp.src('sheetgmail/index.html'),
'headscript': {
src: null,
tpl: '%s'
},
'js': {
src: gulp.src('sheetgmail/app.js'),
tpl: "<script type='text/javascript'>%s</script>"
},
}, {
keepUnassigned: false,
keepBlockTags: true,
resolvePaths: false
}))
.pipe(gulp.dest('dist/'));
});
});
I am trying to use Webpack to bundle a bunch of files. I have the following in my node code...
webpack({
entry: "./src/test",
output: {
path: __dirname,
filename: "bundle.js"
},
}, function(err, stats){
console.log("I would like to output the created js here");
})
This works fine creating a file called bundle.js but I can't figure out how to output as a string instead.
Basically what you can do is to read the file, and then work with it as you want.
e.g.
import webpack from 'webpack';
const config = require('../webpack.config');
const compiler = webpack(config);
compiler.run((err, stats) => {
const data = stats.toJson();
const app = data.assetsByChunkName.app[0] //here you can get the file name
// if you don't have chunks then you should use data.assets;
const file = fs.readFileSync('path to your output ' + app); //read the file
//now you can work with the file as you want.
});
//Basic webpack.config.js
module.exports = {
devtool: 'source-map',
entry: {
app: 'Some path' // you can have different entries.
entrie2 : ''
.... more entries
},
output: {
path: 'Some path'
}
}
Hope this help.
I'm trying to create new grunt task for generating sprites for magento2. I'm using grunt-spritesmith plugin for that. In Gulpfile.js I have mapped sprite task to grunt-spritesmith in JitGrunt config:
require('load-grunt-config')(grunt, {
configPath: path.join(__dirname, configDir),
init: true,
jitGrunt: {
staticMappings: {
usebanner: 'grunt-banner',
sprite: 'grunt-spritesmith'
}
}
});
in dev/tools/grunt/configs I made a config file sprite.js with contents:
'use strict';
module.exports = {
sprite: {
all: {
src: 'app/design/frontend/vendor/default/web/images/spritesheets/*.png',
dest: 'app/design/frontend/vendor/default/web/images/spritesheets.png',
destCss: 'app/design/frontend/vendor/default/web/css/source/_sprites.less'
}
}
};
But grunt sprite gives me
>> No "sprite" targets found.
Or if in different configurations I'm able to register sprite task, I'm not able to pass config with src, dest and destCss params.
You have not include task name. This works:
'use strict';
module.exports = {
all: {
src: 'app/design/frontend/vendor/default/web/images/spritesheets/*.png',
dest: 'app/design/frontend/vendor/default/web/images/spritesheets.png',
destCss: 'app/design/frontend/vendor/default/web/css/source/_sprites.less'
}
};
I'm trying to set up assetmanager
for my blog that has three modules
default
login
admin
I tried like
assets.json
{
"css": {
"app":{
"public/src/dist/default/css/dist.min.css": [
"public/src/assets/default/css/*.css"
]
},
"login":{
"public/src/dist/login/css/dist.min.css": [
"public/src/assets/default/css/*.css"
]
},
"admin":{
"public/src/dist/admin/css/dist.min.css": [
"public/src/assets/admin/css/*.css"
]
}
}
}
express.js
assetmanager.init({
js: assets.js,
css: assets.css,
debug: (process.env.NODE_ENV !== 'production'),
webroot: 'public'
});
// Add assets to local variables
app.use(function(req, res, next) {
res.locals({
assets: assetmanager.assets
});
next();
});
console.log(assetmanager.assets);
but console.log(assetmanager.assets);
give me a empty array []
so is there a way to manage assetmanager
with more than one module ?
the best way I found up to now
is like in my controllers:
'use strict';
var assetmanager = require('assetmanager');
exports.render = function(config) {
var assets = require(config.sroot+'/config/assets.json');
assetmanager.init({
js: assets.js.app,
css: assets.css.app,
debug: (process.env.NODE_ENV !== 'production'),
webroot: 'public'
});
return function(req, res) {
res.render('layouts/default', {appTitle:'ilwebdifabio',assets:assetmanager.assets});
}
};
but it's quite ugly and I have
duplicate code :(
END UP
There is no way to use assetmanager module
in different modules (login,default,admin).
Modules are automatically cached by the Node.js application upon first load. As such, repeated calls to require() - the global method that loads modules - will all result in a reference to the same cached object.
so you end up ie if you use in a module
to the have the dedicate assets in all other module so
I worked it out with :
'use strict';
var _ = require('lodash');
module.exports = function (path,route) {
var env = (process.env.NODE_ENV === 'production') ? 'production' : null;
var debug = (env !== 'production');
var data = require(path+'/config/assets.json');
var assets = {
css: [],
js: []
};
var getAssets = function (pattern) {
var files = [];
if (_.isArray(pattern)) {
_.each(pattern, function (path) {
files = files.concat(getAssets(path));
});
} else if (_.isString(pattern)) {
var regex = new RegExp('^(//)');
if (regex.test(pattern)) {
// Source is external
//For the / in the template against 404
files.push(pattern.substring(1));
} else {
files.push(pattern);
}
}
return files;
};
var getFiles = function () {
var current = data[route];
_.each(['css', 'js'], function (fileType) {
_.each(current[fileType], function (value, key) {
if (!debug) {
assets[fileType].push(key);
} else {
assets[fileType] = assets[fileType].concat(getAssets(value));
}
});
});
};
var getCurrentAssets = function(){
return assets;
};
getFiles();
return {
getCurrentAssets: getCurrentAssets
};
};
in the controller
var assetmanager = require(config.sroot+'/utils/assetsmanager')(config.sroot,'app');
res.render('layouts/default', {
assets:assetmanager.getCurrentAssets()
});
There is a new version of assetmanager 1.0.0 that I believe accomplishes what you're trying to do more effectively. In the new version you can break apart your assets into groups so that you can support multiple layouts. The github has a complete example here but essentially your asset files ends up looking something like this:
{
"main": {
"css": {
"public/build/css/main.min.css": [
"public/lib/bootstrap/dist/css/bootstrap.css",
"public/css/**/*.css"
]
},
"js": {
"public/build/js/main.min.js": [
"public/lib/angular/angular.js",
"public/js/**/*.js"
]
}
},
"secondary": {
"css": {
"public/build/css/secondary.min.css": [
"public/css/**/*.css"
]
},
"js": {
"public/build/js/secondary.min.js": [
"public/js/**/*.js"
]
}
}
}
And then in your layouts you just include the group you want. Hopefully that helps out.