Multiple sources for Gulp task - gulp

I am trying to accomplish a few tasks that I feel like should be relatively basic but I am having a really hard time figuring what I am doing wrong.
I need to:
lint javascript that I have written,
concat javascript that I have written with 3rd party javascript downloaded via NPM,
uglify it
I store paths in my package.json file, so I have this for my app libraries:
{
...,
"paths": {
"src": {
"js": "./src/js/",
"appLibraries": [
"./node_modules/jquery/dist/jquery.js",
"./node_modules/slick-carousel/slick/slick.js"
},
"dist": {
"js": "./build/js"
}
}
}
I have a simple jshint function:
function lintScripts() {
return gulp
.src( pkg.paths.src.js + '**/*.js' )
.pipe( $.jshint() )
.pipe( $.jshint.reporter( 'jshint-stylish' )
}
This works fine. My function to actually compile my JS:
function scripts() {
lintScripts();
return gulp
.src( pkg.paths.src.js + '**/*.js', pkg.paths.src.appLibraries )
// do my other stuff
.pipe( gulp.dest( pkg.paths.dist.js )
}
When I do this, I only get the first argument actually processed. I've tried swapping the src line for this: .src([ pkg.paths.src.js + '**/*.js', pkg.paths.src.appLibraries ]) since I know it can accept an array, but apparently it can't accept an array of arrays because I get this error: Invalid glob argument after ./src/js/**/*.js
I can get around this by updated my package.json paths to the following, but this seems silly and redundant:
{
...,
"paths": {
"src": {
"js": "./src/js/",
"appLibraries": [
"./node_modules/jquery/dist/jquery.js",
"./node_modules/slick-carousel/slick/slick.js",
"./src/js/**/*.js"
},
"dist": {
"js": "./build/js"
}
}
}
What am I missing???

Besides a couple of typos in the code you presented, it does work for me if I put the array ( pkg.paths.src.appLibraries) first and spreading that array and puuting the whole thing in an array as in:
.src( [...pkg.paths.src.appLibraries, pkg.paths.src.js + '**/*.js'] )
don't ask me why these changes makes a difference - I looked through gulpjs issues and src documentation and couldn't find anything that indicated it should be necessary. I would recommend filing an issue there yourself but it may sit awhile.
Perhaps gulp.src can take an array or a string but not both. The documentation could be more formal on this point...
You can always add a src later like this:
function scripts() {
return gulp
.src(pkg.paths.src.js + '**/*.js')
.pipe(gulp.src(pkg.paths.src.appLibraries))
.pipe( gulp.dest( pkg.paths.dist.js ))
};

I never solved this the "right" way, but what I did for anyone having the same issue is I made a variable to grab the array from my package.json, then pushed my new string to the end of it.

Related

Rest-spread not being transpiled when targeting edge with NextJS

I am trying to transpile my ES6 code via Babel, I am using the next/babel preset along with preset-env and I'm using the browsers: defaults target.
The NextJS preset comes with #babel/plugin-proposal-object-rest-spread in its plugins array, I'm wondering why I am getting an error when testing on edge that says Expected identifier, string or number, and when looking in the compiled JS for the error, I see it happens when {...t} occurs.
Here is my babel.config.js:
module.exports = {
presets: [
[
'next/babel',
{
'#babel/preset-env': {
targets: {
browsers: 'defaults'
},
useBuiltIns: 'usage'
}
}
]
],
plugins: [
'#babel/plugin-proposal-optional-chaining',
'#babel/plugin-proposal-nullish-coalescing-operator',
['styled-components', { ssr: true, displayName: true, preprocess: false }],
[
'module-resolver',
{
root: ['.', './src']
}
]
],
env: {
development: {
compact: false
}
}
};
Any help on this would be greatly appreciated!
In the end my problem was related to a package that was not being transpiled by babel. My solution was to use NextJS' next-transpile-modules plugin to get babel to transpile the package code into something that would work on the browsers I need.
Here's an example of my NextJS webpack config with the package I need transpiled specified:
const withTM = require('next-transpile-modules');
module.exports = withTM({
transpileModules: ['swipe-listener']
});
SCRIPT1028: Expected identifier, string or number error can occur in 2 situations.
(1) This error get trigger if you are using trailing comma after your last property in a JavaScript object.
Example:
var message = {
title: 'Login Unsuccessful',
};
(2) This error get trigger if you are using a JavaScript reserved word as a property name.
Example:
var message = {
class: 'error'
};
solution is to pass the class property value as a string. You will need to use bracket notation, however, to call the property in your script.
Reference:
ERROR : SCRIPT1028: Expected identifier, string or number

Vue js external data object

I'm just starting out and have gone through the Vue guide. I've got some basic grasp on imports and exports of ES6 but wanted to know the ideal way of doing this.
I'll have several components that need an original single source of data that i'll need to individually manipulate from there. Ideally I want that data to be in a separate file so that others can manipulate it.
I can figure out to do this via jquery ( seen below ) but I don't really need to make a call as the json file will be internal:
module.exports = {
data: function () {
return {
msg: 'hello',
whatever : 'hi'
}
},
created : function() {
this.fetchData();
},
methods : {
fetchData : function() {
console.log("WORKING");
var self = this;
$.get( apiURL, function( data ) {
self.items = data;
console.log(data);
});
}
}
}
But I also don't want to have all the data be in the App.vue file. I need it somewhere else and then need it to replace my data.
Is the best way to do this to create another Vue file with no template or styling and just create it's own module.exports data object? Say mydata.vue:
module.exports = {
data: function () {
_mydata = {
items : [
{case:'caseone'},
{case:'casetwo'}
],
otheritems : [
{case:'caseone'},
{case:'casetwo'}
]
}
}
}
And then somehow replacing this data object in mydata.vue with the data object in app.vue with imports ( main. js ) ?
import Vue from 'vue'
import App from './App.vue'
import Data from './SiteData.vue'
Just wanted to check if this was the ideal way/i'm on the right path...or if there is an easier way to have a central data object in a different file for all my components?
What I have done is to manage my data in a json file. I think that the approach of use separate files for initial data is cool for small apps. Bigger apps need something more usefull like Vuex.
I don't think it is a good idea to manage a .vue file, as those files are meant to be handled by some module budled system, with the correspondind vue transformation, not the case of the data object.
My approach was this: I had a data.json file
data.json
{
"component1": {
"someData": "someValue",
...
},
...
"componentN": {
"someOtherData": "someOtherValue"
}
}
And then I import that data in the corresponding component
componentN.vue
<template>
</template>
<script>
import { componentN } from './data.json'
export default {
data () {
return componentN
}
}
</script>
Note that:
I used a single file for manage data, however you can split it in a file for every component, for example.
As you can see, this approach can become a mess with medium apps, I don't want to even imagin it in big apps, so be careful.

"this" in underscore is undefined after compiling with browserify and debowerify

So first.. I have next gulp task:
gulp.task('js', function() {
browserify('./src/js/main.js')
.bundle()
.on('error', onError)
.pipe( source('main.js') )
.pipe( gulp.dest(path.build.js) );
});
and package.json:
{
"browserify": {
"transform": [
["babelify", { "presets": ["es2015"] }],
"debowerify"
]
},
}
I am importing Backbone in main.js (or only underscore... it doesn't matter)
import Backbone from 'backbone';
And in console I am getting error
Uncaught TypeError: Cannot read property '_' of undefined
I checked code and found that in underscore sources at start of library root is undefined
// Establish the root object, `window` in the browser, or `exports` on the server.
var root = this;
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
I think the problem is that debowerify or babelfy is wrapping code in some function. But also if I use node modules without debowerify all works fine. But I want to use bower.
So how to fix this problem?
To any future visitors to this question,
this is similar to Underscore gives error when bundling with Webpack
The gist of the issue is that babel is probably running the underscore.js code, since underscore.js uses this, and in es6 this is undefined when outside of a function, naturally this._ fails.
In code I've fixed the issue by ensuring that babel does not run on node_modules.
In my case the same error arose when using just browserify with underscore. I've workarounded issue by switching from underscore to lodash. They are in general (surely not fully) compatible, but at the worst I'd rather copy some missing function from underscore sources than live with its deisolated load approach.

How can I set the correct order of files to be concatenated with gulp-bundle-assets

I use gulp-bundle-assets for processing my static resources. I have the next configuration in my bundle.config.js:
module.exports = {
bundle: {
...
vendor: {
scripts: [
'./bower_components/angular/angular.js',
'./bower_components/angular-aria/angular-aria.js',
'./bower_components/angular-material/angular-material.js',
'./bower_components/angular-translate/angular-translate.js',
'./bower_components/angular-animate/angular-animate.js'
]
options: {
uglify: false,
order: {
scripts: [
'angular.js',
'*.js'
]
}
}
}
},
...
};
Thus, the first script to be concatenated must be angular.js, but "options.order" doesn't work correct - the first concatenated file in the final script is angular-animate.js. So, my question is how to achieve the correct order?
I'm the author of gulp-bundle-assets. The problem is with your glob syntax. Under the covers, gulp-bundle-assets uses gulp-order, which itself uses minimatch. The docs for each give lots of examples but for your particular use-case, this minimatch example shows your problem:
var minimatch = require("minimatch")
minimatch("./bower_components/angular/angular.js", "angular.js") // false
minimatch("./bower_components/angular/angular.js", "./**/angular.js") // true
Unfortunately the ./ at the beginning is throwing off minimatch. The following should fix your problem:
options: {
order: {
scripts: [
'./**/angular.js',
'./**/*.js'
]
}
}
Hope that helps.

In the Grunt.js docs, there is a "this.filessrc" option, is it possible to do "this.filesDest"?

I created a Grunt plugin for generating "manifests" in YAML or JSON format. For instance, the task can create package.json or component.json from given metadata, or by using the metadata from one of those files to build the other.
The task also includes an option for reading directories of files to generate "collections" out of files with certain file extensions. So, for example, you can create a "component" manifest that lists out the files required by the component:
{
"name": "My Component",
"description": "",
"version": "",
"scripts": {
"jquery.js",
"component.js"
"one.js",
"two.js",
"three.js"
},
"styles": {
"component.css"
}
}
So, both src and dest are used in the task for building the "collections", however, when you are only generating a package.json or component.json for instance, you only need the dest.
I didn't find a native Grunt method for doing this, or another clean way of accomplishing the same goal?
You can use one of:
grunt.file.expand
grunt.task.normalizemultitaskfiles
Example (simplified):
module.exports = function( grunt ) {
"use strict";
var util = require('util');
grunt.initConfig({
pkg: grunt.file.readJSON("package.json")
});
grunt.registerTask('default', ['normalizeMultiTaskFiles', 'expand']);
grunt.registerTask('normalizeMultiTaskFiles', function(pattern) {
var result = grunt.task.normalizeMultiTaskFiles(['./public/**/*']);
console.log(util.inspect(result[0].src));
});
grunt.registerTask('expand', function() {
var result = grunt.file.expand(['./public/**/*']);
console.log(util.inspect(result));
})
};
Output:
Running "normalizeMultiTaskFiles" task
[ './public/css',
'./public/css/main.css',
'./public/index.html',
'./public/js',
'./public/js/file1.js',
'./public/js/file2.js',
'./public/js/file3.js',
'./public/js/index.js',
'./public/js/lib',
'./public/vendor',
'./public/vendor1.js',
'./public/vendor2.js' ]
Running "expand" task
[ './public/css',
'./public/css/main.css',
'./public/index.html',
'./public/js',
'./public/js/file1.js',
'./public/js/file2.js',
'./public/js/file3.js',
'./public/js/index.js',
'./public/js/lib',
'./public/vendor',
'./public/vendor1.js',
'./public/vendor2.js' ]