I just purchased the Keen theme from Bootstrap and whilst following the instructions to the letter I ran into an error executing 'npm run build' (see below). I've looked at the web pack.config.js file (see below), but as it's something I've not looked at in depth I can't figure out where the problem is. Any help will be greatly appreciated, thanks!
Error output:
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'build' ]
2 info using npm#6.13.6
3 info using node#v13.8.0
4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
5 info lifecycle keen#1.4.2~prebuild: keen#1.4.2
6 info lifecycle keen#1.4.2~build: keen#1.4.2
7 verbose lifecycle keen#1.4.2~build: unsafe-perm in lifecycle true
8 verbose lifecycle keen#1.4.2~build: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/Users/julian/Downloads/compile/node_modules/.bin:/Users/julian/.rvm/gems/ruby-2.6.5/bin:/Users/julian/.rvm/gems/ruby-2.6.5#global/bin:/Users/julian/.rvm/rubies/ruby-2.6.5/bin:/Users/julian/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public/:/Users/julian/.rvm/bin
9 verbose lifecycle keen#1.4.2~build: CWD: /Users/julian/Downloads/compile
10 silly lifecycle keen#1.4.2~build: Args: [ '-c', 'webpack' ]
11 silly lifecycle keen#1.4.2~build: Returned: code: 1 signal: null
12 info lifecycle keen#1.4.2~build: Failed to exec build script
13 verbose stack Error: keen#1.4.2 build: `webpack`
13 verbose stack Exit status 1
13 verbose stack at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:332:16)
13 verbose stack at EventEmitter.emit (events.js:321:20)
13 verbose stack at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 verbose stack at ChildProcess.emit (events.js:321:20)
13 verbose stack at maybeClose (internal/child_process.js:1026:16)
13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
14 verbose pkgid keen#1.4.2
15 verbose cwd /Users/julian/Downloads/compile
16 verbose Darwin 19.3.0
17 verbose argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "build"
18 verbose node v13.8.0
19 verbose npm v6.13.6
20 error code ELIFECYCLE
21 error errno 1
22 error keen#1.4.2 build: `webpack`
22 error Exit status 1
23 error Failed at the keen#1.4.2 build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]
webpack.config.js:
/**
* Main file of webpack config.
* Please do not modified unless you know what to do
*/
const path = require("path");
const glob = require("glob");
const webpack = require("webpack");
const fs = require("fs");
const parser = require("comment-parser");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const WebpackRTLPlugin = require("webpack-rtl-plugin");
const TerserJSPlugin = require("terser-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const WebpackMessages = require("webpack-messages");
const ExcludeAssetsPlugin = require("webpack-exclude-assets-plugin");
const atob = require("atob");
const slash = require("slash");
const del = require("del");
// optional
const ReplaceInFileWebpackPlugin = require("replace-in-file-webpack-plugin");
/**
* Known issues:
* 1) Remove webpack bootstrap for single-module apps
* https://github.com/webpack/webpack/issues/2638
*/
// arguments/params from the line command
const args = {};
// remove first 2 unused elements from array
const argv = JSON.parse(process.env.npm_config_argv).cooked.slice(2);
argv.forEach((arg, i) => {
if (arg.match(/^--/)) {
const next = argv[i + 1];
args[arg] = true;
if (next && !next.match(/^--/)) {
args[arg] = argv[i + 1];
}
}
});
// read parameters from the command executed by user
const rtl = args["--rtl"] || false;
const prod = args["--prod"] || false;
const css = args["--css"] || true;
const js = args["--js"] || true;
// theme name
const themeName = "keen";
// global variables
const release = true;
const apiUrl = false; // boolean
const rootPath = path.resolve(__dirname, "..");
const frameworkPath = path.resolve(__dirname, "..");
const distPath = rootPath + "/dist";
const configPath = rootPath + "/tools";
const assetDistPath = distPath + "/assets";
const srcPath = rootPath + "/src/assets";
// page scripts and styles
const pageScripts = glob.sync(srcPath + "/js/pages/**/!(_*).js");
const pagesScss = glob.sync(srcPath + "/sass/pages/**/!(_*).scss");
const extraPlugins = [];
const filesConfig = [];
const imageReference = {};
const exclude = [];
const nodeMedia = [];
// remove older folders and files
// (async () => {
// await del.sync(assetDistPath, {force: true});
// })();
// get all assets config
let files = glob.sync(configPath + "/webpack/**/*.js");
// parse comments to get the output location
files.forEach((filename) => {
// get file content
const text = fs.readFileSync(filename).toString();
// use parser plugin to parse the comment.
const parsed = parser(text);
if (parsed.length > 0 && parsed[0].tags.length > 0) {
// push to list
filesConfig.push({
filename: filename,
params: parsed[0].tags,
});
}
});
const entries = {};
filesConfig.forEach((file) => {
let output = "";
file.params.forEach((param) => {
// get output path
if (param.tag === "output") {
output = param.name;
}
});
entries[output] = file.filename;
});
// process skin scss
const skinScss = glob.sync(srcPath + "/sass/**/skins/**/!(_*|style*).scss");
skinScss.forEach((file) => {
const matched = file.match(/sass\/global\/layout\/(.*?)\.scss$/);
if (matched) {
entries["css/skins/" + matched[1].replace(/\/skins\//, "/")] = file;
}
});
// process pages scss
pagesScss.forEach((file) => {
const matched = file.match(/\/(pages\/.*?)\.scss$/);
if (matched) {
// keep image reference for output path rewrite
const imgMatched = fs.readFileSync(file).toString().match(/['|"](.*?\.(gif|png|jpe?g))['|"]/g);
if (imgMatched) {
imgMatched.forEach((img) => {
img = img.replace(/^['|"](.+(?=['|"]$))['|"]$/, '$1');
imageReference[path.basename(img)] = "css/" + matched[1] + ".css";
});
}
entries['css/' + matched[1]] = file;
}
});
// auto get page scripts from source
pageScripts.forEach(function (jsPath) {
const matched = jsPath.match(/js\/(pages\/.*?)\.js$/);
entries["js/" + matched[1]] = jsPath;
});
if (release) {
// copy html by demo
extraPlugins.push(new CopyWebpackPlugin([{
from: rootPath + "/src",
to: distPath,
}]));
}
if ((/true/i).test(rtl)) {
// enable rtl for css
extraPlugins.push(new WebpackRTLPlugin({
filename: "[name].rtl.css",
}));
}
if (!(/true/i).test(js)) {
// exclude js files
exclude.push('\.js$');
}
if (!(/true/i).test(css)) {
// exclude css files
exclude.push('\.s?css$');
}
if (exclude.length) {
// add plugin for exclude assets (js/css)
extraPlugins.push(new ExcludeAssetsPlugin({
path: exclude
}));
}
if (apiUrl) {
// replace api url to point to server
extraPlugins.push(new ReplaceInFileWebpackPlugin([{
dir: assetDistPath + "/js",
test: /\.js$/,
rules: [{
search: /inc\/api\//i,
replace: 'https://keenthemes.com/' + themeName + '/tools/preview/'
}]
}]));
}
const mainConfig = function () {
return {
// enabled/disable optimizations
mode: (/true/i).test(prod) ? "production" : "development",
// console logs output, https://webpack.js.org/configuration/stats/
stats: "errors-warnings",
performance: {
// disable warnings hint
hints: false
},
optimization: {
// js and css minimizer
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
entry: entries,
output: {
// main output path in assets folder
path: assetDistPath,
// output path based on the entries' filename
filename: "[name].js"
},
resolve: {
alias: {
"morris.js": "morris.js/morris.js",
"jquery-ui": "jquery-ui",
}
},
plugins: [
// webpack log message
new WebpackMessages({
name: themeName,
logger: str => console.log(`>> ${str}`)
}),
// create css file
new MiniCssExtractPlugin({
filename: "[name].css",
}),
// copy media
new CopyWebpackPlugin([{
from: srcPath + "/media",
to: assetDistPath + "/media",
}]),
{
apply: (compiler) => {
// hook name
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
filesConfig.forEach((file) => {
let output = "";
file.params.forEach((param) => {
// get output path
if (param.tag === "output") {
output = param.name;
}
if (param.tag === "images") {
param.name.split(",").forEach((file) => {
if (file) {
const outputPath = assetDistPath + "/" + pathWithoutFile(output) + "/images/";
// create dir
fs.mkdirSync(outputPath, {recursive: true});
// copy image
fs.copyFileSync(fs.realpathSync(srcPath + "/" + file), outputPath + path.basename(file));
}
});
}
});
});
});
}
},
].concat(extraPlugins),
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
],
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "sass-loader",
options: {
sourceMap: true,
// // use for separate css pages (custom pages, eg. wizard, invoices, etc.)
// includePaths: demos.map((demo) => {
// return slash(srcPath) + "/sass/theme/demos/" + demo;
// })
}
},
]
},
{
test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
include: [
path.resolve(__dirname, "node_modules"),
rootPath,
frameworkPath,
],
use: [
{
loader: "file-loader",
options: {
// prevent name become hash
name: "[name].[ext]",
// move files
outputPath: "plugins/global/fonts",
// rewrite path in css
publicPath: "fonts",
}
}
]
},
{
test: /\.(gif|png|jpe?g)$/,
include: [
path.resolve(__dirname, "node_modules"),
rootPath,
],
use: [{
loader: "file-loader",
options: {
// prevent name become hash
name: "[name].[ext]",
// move files
outputPath: (url, resourcePath) => {
// look for node_modules plugin
const matched = slash(resourcePath).match(/node_modules\/(.*?)\//);
if (matched) {
for (let i = 0; i < filesConfig.length; i++) {
if (filesConfig[i].filename.match(new RegExp(matched[1]))) {
let output = "";
filesConfig[i].params.forEach((param) => {
// get output path without filename
if (param.tag === "output") {
output = pathWithoutFile(param.name);
}
});
nodeMedia[url] = output + "/images/" + url;
return output + "/images/" + url;
}
}
}
// the rest of images put in media/misc/
return "media/misc/" + url;
},
// rewrite path in css
publicPath: (url, resourcePath) => {
if (imageReference[url]) {
// fix image rewrite path
const filePath = pathWithoutFile(imageReference[url]);
return slash(path.relative(assetDistPath + "/" + filePath, assetDistPath + "/media") + "/" + url);
}
if (nodeMedia[url]) {
return "images/" + url;
}
return "../../media/misc/" + url;
},
}
}]
},
]
},
// webpack dev server config
devServer: {
contentBase: distPath,
compress: true,
port: 3000
}
}
};
module.exports = function () {
return [mainConfig()];
};
function pathWithoutFile(filname) {
return filname.substring(0, filname.lastIndexOf("/"));
}
I just realized I forgot to include the src directory in the same parent directory as the included tools directory (:face_palm!)
Related
I'm using Quasar for SPA only. But I don't need all the things that come with Quasar CLI.
Is there a way to eject Quasar CLI and start using Vue + Quasar UMD?
Basically, stop using quasar dev and start using vue serve?
Yes, you can. The following changes should be made:
// vue.config.js
const QuasarLoader = require('./quasar-loader/index');
module.exports =
{
css:
{
loaderOptions:
{
scss:
{
prependData: `#import "~quasar/src/css/variables.sass";`
}
}
},
transpileDependencies: ['quasar'],
configureWebpack: (config) =>
{
if (!config.plugins) config.plugins = [];
config.plugins.push(new QuasarLoader());
},
}
// quasar-loader/auto-import.js
/**
* Quasar runtime for auto-importing
* components or directives.
*
* Warning! This file does NOT get transpiled by Babel
* but is included into the UI code.
*
* #param component {Vue} Component object
* #param type {String} One of 'components' or 'directives'
* #param items {Object} Object containing components or directives
*/
module.exports = function quasarLoader(component, type, items)
{
/* we use a workaround in functional templates
<template>
<component :is="$options.components.QBtn" ... />
</template>
*/
var target, i;
var opt = component.options;
if (!opt[type])
{
opt[type] = items
}
else
{
target = opt[type];
for (i in items)
{
if (!target[i])
{
target[i] = items[i]
}
}
}
};
// quasar-loader/index.js
const RuleSet = require('webpack/lib/RuleSet');
let vueLoaderPath;
try
{
vueLoaderPath = require.resolve('vue-loader');
}
catch (err)
{}
function isVueLoader(use)
{
return use.ident === 'vue-loader-options' ||
use.loader === 'vue-loader' ||
(vueLoaderPath && use.loader === vueLoaderPath)
}
class QuasarLoaderPlugin
{
constructor(options)
{
this.options = options || {}
}
apply(compiler)
{
// use webpack's RuleSet utility to normalize user rules
const rawRules = compiler.options.module.rules;
const { rules } = new RuleSet(rawRules);
// find the rule that applies to vue files
const vueRuleIndex = rules.findIndex(rule => rule.use && rule.use.find(isVueLoader));
const vueRule = rules[vueRuleIndex];
if (!vueRule)
{
throw new Error(
`[QuasarLoaderPlugin Error] No matching rule for vue-loader found.\n` +
`Make sure there is at least one root-level rule that uses vue-loader.`
)
}
vueRule.use.unshift({
loader: require.resolve('./loader'),
options: this.options || { nameCase: 'kebab' }
});
compiler.options.module.rules = rules;
}
}
module.exports = QuasarLoaderPlugin;
// quasar-loader/loader.js
const path = require('path');
const compiler = require('vue-template-compiler');
// const loaderOptions = require('loader-utils/lib/getOptions');
const stringifyRequest = require('loader-utils/lib/stringifyRequest');
const importData = require('quasar/dist/babel-transforms/auto-import.json');
const importTransform = require('quasar/dist/babel-transforms/imports.js');
const runtimePath = require.resolve('./auto-import.js');
// regex to match functional components
const funcCompRegex = new RegExp(
'var\\s+component\\s*=\\s*normalizer\\((?:[^,]+,){3}\\s*true,'
);
function transform(itemArray)
{
return itemArray
.map(name => `import ${name} from '${importTransform(name)}'`)
.join(`\n`)
}
module.exports = async function (content, sourceMap)
{
this.async();
this.cacheable();
if (!this.resourceQuery)
{
const readFile = path => new Promise((resolve, reject) =>
{
this.fs.readFile(path, function (err, data)
{
if (err) reject(err);
else resolve(data)
})
});
this.addDependency(this.resourcePath);
const tags = new Set();
const directives = new Set();
const file = (await readFile(this.resourcePath)).toString('utf8');
const component = compiler.parseComponent(file);
if (component.template)
{
if (component.template.src)
{
const externalFile = (await new Promise((resolve, reject) =>
this.resolve(path.dirname(this.resourcePath), component.template.src, (err, result) =>
{
if (err) reject(err);
else resolve(result)
})
));
component.template.content = (await readFile(externalFile)).toString('utf8'); // external content
}
const compRegexKebab = new RegExp('^' + importData.regex.kebabComponents + '$');
const compRegexPascal = new RegExp('^' + importData.regex.pascalComponents + '$');
const dirRegex = new RegExp('^' + importData.regex.directives + '$');
compiler.compile(component.template.content, {
modules: [{
postTransformNode: node =>
{
if ("directives" in node)
{
node.directives.forEach(({ name }) =>
{
if (dirRegex.test('v-' + name))
{
directives.add(importData.importName['v-' + name]);
}
});
}
if (compRegexKebab.test(node.tag))
{
tags.add(importData.importName[node.tag]);
}
else if (compRegexPascal.test(node.tag))
{
tags.add(node.tag);
}
}
}]
});
const arrTags = [...tags];
const arrDirs = [...directives];
if (arrTags.length > 0 || arrDirs.length > 0)
{
const functional = funcCompRegex.test(content);
let newContent = '/* quasar-loader */\n';
newContent += `import qInstall from ${stringifyRequest(this, runtimePath)}\n`;
if (arrTags.length > 0)
{
if (functional) console.error('Using workaround for local Vue components (' + arrTags.join(',') + ') in a functional template.');
newContent += transform(arrTags) + '\n';
newContent += `qInstall(component, "components", {${arrTags.join(",")}})\n`;
}
if (arrDirs.length > 0)
{
if (functional) console.error('Using local Vue directive (' + arrDirs.join(',') + ') in a functional component is not supported.');
newContent += transform(arrDirs) + '\n';
newContent += `qInstall(component, "directives", {${arrDirs.join(",")}})\n`;
}
// Insert our modification before the HMR code
const hotReload = content.indexOf('/* hot reload */');
if (hotReload > -1)
{
content = content.slice(0, hotReload) + newContent + '\n\n' + content.slice(hotReload)
}
else
{
content += '\n\n' + newContent
}
}
}
}
this.callback(null, content, sourceMap);
};
// src/main.js
import QuasarInstall from 'quasar/src/vue-plugin'
import iconSet from 'quasar/icon-set/svg-mdi-v5'
// import QuasarDialog from 'quasar/src/plugins/Dialog'
import '#/assets/scss/quasar.scss'
QuasarInstall.install(Vue, {
iconSet,
plugins:
{
// Dialog: QuasarDialog,
},
});
// src/assets/scss/quasar.scss
$primary : #409EFF;
$secondary : #26A69A;
$accent : #9C27B0;
$dark : #1D1D1D;
$positive : #20A835;
$negative : #F04025;
$info : #1975D0;
$warning : #F2C037;
#import '~quasar/src/css/index.sass';
If you want to use Quasar and Vue without CLI at all, you can check this starter project.
It's just Quasar UMD (ver.2) and vanilla Vue (ver.3).
Github: https://github.com/SaleCar/Quasar-UMD-Template
Demo: http://quasar.rf.gd/
I am making edits to my JS files but my gulp task is not updating them live or writing new code. It did used to work but all of a sudden it has stopped.
I tried upgrading the gulp to version 4 but that just created more issues and didn't fix the fact the JS wasn't working.
Added jshint to see if that threw any errors but seems fine too.
'use strict';
const
// source and build folders
dir = {
src : './src/',
build : './'
},
// Gulp and plugins
gulp = require('gulp'),
gutil = require('gulp-util'),
newer = require('gulp-newer'),
imagemin = require('gulp-imagemin'),
sass = require('gulp-sass'),
postcss = require('gulp-postcss'),
deporder = require('gulp-deporder'),
concat = require('gulp-concat'),
stripdebug = require('gulp-strip-debug'),
uglify = require('gulp-uglify'),
ftp = require( 'vinyl-ftp' ),
jshint = require('gulp-jshint');
// configure the jshint task
gulp.task('jshint', function() {
return gulp.src(dir.src + '/assets/js/*.js')
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'));
});
// Browser-sync
var browsersync = false;
//Dev FTP Connections
function getDevFtpConnection() {
return ftp.create({
host: '109.169.64.171',
// port: 20,
user: 'admin#powdersky.net',
password: '=Lx0$Zf=a}ZW',
parallel: 5,
log: gutil.log
});
}
//Deploy to dev
gulp.task('ftp-deploy-dev', function() {
var conn = getDevFtpConnection();
return gulp.src([dir.build + '/**/**/**/*',
"!./{src/,src/**/*}",
"!./{node_modules/,node_modules/**/**/**/*}",
"!./gulpfile.js",
"!./package-lock.json",
"!./package.json"], { base: '.', buffer: false })
.pipe( conn.newer( '/inthesnow.com/wp-content/themes/inthesnow/' ) ) // only upload newer files
.pipe( conn.dest( '/inthesnow.com/wp-content/themes/inthesnow/' ) )
;
});
// PHP settings
const php = {
src : dir.src + 'templates/**/*.php',
build : dir.build
};
// copy pugins files
gulp.task('php', () => {
return gulp.src([
dir.build + '/includes/**/**/**/*.php',
dir.build + '*.php'
])
.pipe(newer(dir.build))
.pipe(gulp.dest(dir.build))
.pipe(browsersync ? browsersync.reload({ stream: true }) : gutil.noop());
});
gulp.task('php-templates', () => {
return gulp.src([
dir.build + '*.php'
])
.pipe(newer(dir.build))
.pipe(gulp.dest(dir.build))
.pipe(browsersync ? browsersync.reload({ stream: true }) : gutil.noop());
});
// image settings
const images = {
src : dir.src + 'assets/images/**/*',
build : dir.build + 'assets/images/'
};
// image processing
gulp.task('images', () => {
return gulp.src(images.src)
.pipe(newer(images.build))
.pipe(imagemin())
.pipe(gulp.dest(images.build));
});
// CSS settings
var css = {
src : dir.src + 'assets/scss/style.scss',
watch : dir.src + 'assets/scss/**/**/*',
build : dir.build,
sassOpts: {
outputStyle : 'compressed',
imagePath : images.build,
precision : 3,
errLogToConsole : true
},
processors: [
require('postcss-assets')({
loadPaths: ['images/'],
basePath: dir.build,
baseUrl: '/wp-content/themes/inthesnow/'
}),
require('autoprefixer')({
browsers: ['last 2 versions', '> 2%']
}),
require('css-mqpacker'),
require('cssnano'),
]
};
// CSS processing
gulp.task('css', ['images'], () => {
return gulp.src([
css.src,
])
.pipe(sass(css.sassOpts))
.pipe(postcss(css.processors))
.pipe(concat('style.css'))
.pipe(gulp.dest(css.build))
.pipe(browsersync ? browsersync.reload({ stream: true }) : gutil.noop());
});
// Vendor JavaScript settings
const build_vendor_js = {
src : dir.src + 'assets/js/vendor/*',
build : dir.build + 'assets/js/',
filename : 'jquery.vendor.js'
};
// JavaScript processing
gulp.task('build_vendor_js', () => {
return gulp.src(build_vendor_js.src)
.pipe(deporder())
.pipe(concat(build_vendor_js.filename))
.pipe(stripdebug())
.pipe(uglify())
.pipe(gulp.dest(build_vendor_js.build))
.pipe(browsersync ? browsersync.reload({ stream: true }) : gutil.noop());
});
// General JavaScript processing
gulp.task('build_general_js', () => {
return gulp.src([
// dir.build + 'includes/plugins/**/assets/js/*.js',
dir.src + 'assets/js/*',
])
.pipe(deporder())
// .pipe(concat('jquery.functions.js'))
.pipe(stripdebug())
.pipe(uglify())
.pipe(gulp.dest(dir.build + 'assets/js/'))
.pipe(browsersync ? browsersync.reload({ stream: true }) : gutil.noop());
});
// run all tasks
gulp.task('build', ['css', 'build_vendor_js','build_general_js']);
// Browsersync options
const syncOpts = {
proxy : 'http://inthesnow',
reloadOnRestart: true,
ui: {
port: 8080
}
};
// browser-sync
gulp.task('browsersync', () => {
if (browsersync === false) {
browsersync = require('browser-sync').create();
browsersync.init(syncOpts);
}
});
// watch for file changes
gulp.task('watch', ['browsersync'], () => {
// page changes
// gulp.watch(php.src, ['php'], browsersync ? browsersync.reload : {});
// gulp.watch(php.src, ['php-templates'], browsersync ? browsersync.reload : {});
// image changes
gulp.watch(images.src, ['images']);
// CSS changes
gulp.watch(css.watch, ['css']);
// JavaScript main changes
gulp.watch([ dir.src + '/assets/js/*.js' ], ['jshint', 'build_general_js']);
//vendor
gulp.watch(build_vendor_js.src, ['build_vendor_js']);
});
gulp.task('default', ['build', 'watch']);
It seems to be correct to me but obviously not! I am assuming something may have updated that has triggered something but cant find which module it could be, the CSS task runs fine as well.
So this was me being silly, I didn't notice the stripdebug module which is was my alert/console.log wasn't working!
Rookie error
I want to see what react-native run-androidis doing under the hood. where can I read what this is doing?
React Native is open source, so you can find the code for the CLI on Github: https://github.com/facebook/react-native/blob/master/local-cli/runAndroid/runAndroid.js
If you prefer to check it locally, you can find the code in your RN project under node_modules/react-native/ where the run-android code is in local-cli/runAndroid/runAndroid.js.
'use strict';
const { getProjectCommands } = require('./core');
import type { RNConfig } from './core';
export type CommandT = {
name: string,
description?: string,
usage?: string,
func: (argv: Array<string>, config: RNConfig, args: Object) => ?Promise<void>,
options?: Array<{
command: string,
description?: string,
parse?: (val: string) => any,
default?: (config: RNConfig) => any | any,
}>,
examples?: Array<{
desc: string,
cmd: string,
}>,
pkg?: {
version: string,
name: string,
},
};
const documentedCommands = [
require('./server/server'),
require('./runIOS/runIOS'),
require('./runAndroid/runAndroid'),
require('./library/library'),
require('./bundle/bundle'),
require('./bundle/unbundle'),
require('./eject/eject'),
require('./link/link'),
require('./link/unlink'),
require('./install/install'),
require('./install/uninstall'),
require('./upgrade/upgrade'),
require('./logAndroid/logAndroid'),
require('./logIOS/logIOS'),
require('./dependencies/dependencies'),
];
// The user should never get here because projects are inited by
// using `react-native-cli` from outside a project directory.
const undocumentedCommands = [
{
name: 'init',
func: () => {
console.log([
'Looks like React Native project already exists in the current',
'folder. Run this command from a different folder or remove node_modules/react-native',
].join('\n'));
},
},
];
const commands: Array<CommandT> = [
...documentedCommands,
...undocumentedCommands,
...getProjectCommands(),
];
module.exports = commands;
I think this is you wanted?
'use strict';
const adb = require('./adb');
const chalk = require('chalk');
const child_process = require('child_process');
const fs = require('fs');
const isPackagerRunning = require('../util/isPackagerRunning');
const isString = require('lodash/isString');
const path = require('path');
const Promise = require('promise');
// Verifies this is an Android project
function checkAndroid(root) {
return fs.existsSync(path.join(root, 'android/gradlew'));
}
/**
* Starts the app on a connected Android emulator or device.
*/
function runAndroid(argv, config, args) {
if (!checkAndroid(args.root)) {
console.log(chalk.red('Android project not found. Maybe run react-native android first?'));
return;
}
if (!args.packager) {
return buildAndRun(args);
}
return isPackagerRunning().then(result => {
if (result === 'running') {
console.log(chalk.bold('JS server already running.'));
} else if (result === 'unrecognized') {
console.warn(chalk.yellow('JS server not recognized, continuing with build...'));
} else {
// result == 'not_running'
console.log(chalk.bold('Starting JS server...'));
startServerInNewWindow();
}
return buildAndRun(args);
});
}
function getAdbPath() {
return process.env.ANDROID_HOME
? process.env.ANDROID_HOME + '/platform-tools/adb'
: 'adb';
}
// Runs ADB reverse tcp:8081 tcp:8081 to allow loading the jsbundle from the packager
function tryRunAdbReverse(device) {
try {
const adbPath = getAdbPath();
const adbArgs = ['reverse', 'tcp:8081', 'tcp:8081'];
// If a device is specified then tell adb to use it
if (device) {
adbArgs.unshift('-s', device);
}
console.log(chalk.bold(
`Running ${adbPath} ${adbArgs.join(' ')}`
));
child_process.execFileSync(adbPath, adbArgs, {
stdio: [process.stdin, process.stdout, process.stderr],
});
} catch (e) {
console.log(chalk.yellow(`Could not run adb reverse: ${e.message}`));
}
}
// Builds the app and runs it on a connected emulator / device.
function buildAndRun(args) {
process.chdir(path.join(args.root, 'android'));
const cmd = process.platform.startsWith('win')
? 'gradlew.bat'
: './gradlew';
const packageName = fs.readFileSync(
`${args.appFolder}/src/main/AndroidManifest.xml`,
'utf8'
).match(/package="(.+?)"/)[1];
const packageNameWithSuffix = args.appIdSuffix ? packageName + '.' + args.appIdSuffix : packageName;
const adbPath = getAdbPath();
if (args.deviceId) {
if (isString(args.deviceId)) {
runOnSpecificDevice(args, cmd, packageNameWithSuffix, packageName, adbPath);
} else {
console.log(chalk.red('Argument missing for parameter --deviceId'));
}
} else {
runOnAllDevices(args, cmd, packageNameWithSuffix, packageName, adbPath);
}
}
function runOnSpecificDevice(args, gradlew, packageNameWithSuffix, packageName, adbPath) {
let devices = adb.getDevices();
if (devices && devices.length > 0) {
if (devices.indexOf(args.deviceId) !== -1) {
buildApk(gradlew);
installAndLaunchOnDevice(args, args.deviceId, packageNameWithSuffix, packageName, adbPath);
} else {
console.log('Could not find device with the id: "' + args.deviceId + '".');
console.log('Choose one of the following:');
console.log(devices);
}
} else {
console.log('No Android devices connected.');
}
}
function buildApk(gradlew) {
try {
console.log(chalk.bold('Building the app...'));
// using '-x lint' in order to ignore linting errors while building the apk
child_process.execFileSync(gradlew, ['build', '-x', 'lint'], {
stdio: [process.stdin, process.stdout, process.stderr],
});
} catch (e) {
console.log(chalk.red('Could not build the app, read the error above for details.\n'));
}
}
function tryInstallAppOnDevice(args, device) {
try {
const pathToApk = `${args.appFolder}/build/outputs/apk/${args.appFolder}-debug.apk`;
const adbPath = getAdbPath();
const adbArgs = ['-s', device, 'install', pathToApk];
console.log(chalk.bold(
`Installing the app on the device (cd android && adb -s ${device} install ${pathToApk}`
));
child_process.execFileSync(adbPath, adbArgs, {
stdio: [process.stdin, process.stdout, process.stderr],
});
} catch (e) {
console.log(e.message);
console.log(chalk.red(
'Could not install the app on the device, read the error above for details.\n'
));
}
}
function tryLaunchAppOnDevice(device, packageNameWithSuffix, packageName, adbPath, mainActivity) {
try {
const adbArgs = ['-s', device, 'shell', 'am', 'start', '-n', packageNameWithSuffix + '/' + packageName + '.' + mainActivity];
console.log(chalk.bold(
`Starting the app on ${device} (${adbPath} ${adbArgs.join(' ')})...`
));
child_process.spawnSync(adbPath, adbArgs, {stdio: 'inherit'});
} catch (e) {
console.log(chalk.red(
'adb invocation failed. Do you have adb in your PATH?'
));
}
}
function installAndLaunchOnDevice(args, selectedDevice, packageNameWithSuffix, packageName, adbPath) {
tryRunAdbReverse(selectedDevice);
tryInstallAppOnDevice(args, selectedDevice);
tryLaunchAppOnDevice(selectedDevice, packageNameWithSuffix, packageName, adbPath, args.mainActivity);
}
function runOnAllDevices(args, cmd, packageNameWithSuffix, packageName, adbPath){
try {
const gradleArgs = [];
if (args.variant) {
gradleArgs.push('install' +
args.variant[0].toUpperCase() + args.variant.slice(1)
);
} else if (args.flavor) {
console.warn(chalk.yellow(
'--flavor has been deprecated. Use --variant instead'
));
gradleArgs.push('install' +
args.flavor[0].toUpperCase() + args.flavor.slice(1)
);
} else {
gradleArgs.push('installDebug');
}
if (args.installDebug) {
gradleArgs.push(args.installDebug);
}
console.log(chalk.bold(
`Building and installing the app on the device (cd android && ${cmd} ${gradleArgs.join(' ')})...`
));
child_process.execFileSync(cmd, gradleArgs, {
stdio: [process.stdin, process.stdout, process.stderr],
});
} catch (e) {
console.log(chalk.red(
'Could not install the app on the device, read the error above for details.\n' +
'Make sure you have an Android emulator running or a device connected and have\n' +
'set up your Android development environment:\n' +
'https://facebook.github.io/react-native/docs/android-setup.html'
));
// stderr is automatically piped from the gradle process, so the user
// should see the error already, there is no need to do
// `console.log(e.stderr)`
return Promise.reject();
}
const devices = adb.getDevices();
if (devices && devices.length > 0) {
devices.forEach((device) => {
tryRunAdbReverse(device);
tryLaunchAppOnDevice(device, packageNameWithSuffix, packageName, adbPath, args.mainActivity);
});
} else {
try {
// If we cannot execute based on adb devices output, fall back to
// shell am start
const fallbackAdbArgs = [
'shell', 'am', 'start', '-n', packageNameWithSuffix + '/' + packageName + '.MainActivity'
];
console.log(chalk.bold(
`Starting the app (${adbPath} ${fallbackAdbArgs.join(' ')}...`
));
child_process.spawnSync(adbPath, fallbackAdbArgs, {stdio: 'inherit'});
} catch (e) {
console.log(chalk.red(
'adb invocation failed. Do you have adb in your PATH?'
));
// stderr is automatically piped from the gradle process, so the user
// should see the error already, there is no need to do
// `console.log(e.stderr)`
return Promise.reject();
}
}
}
function startServerInNewWindow() {
const yargV = require('yargs').argv;
const scriptFile = /^win/.test(process.platform) ?
'launchPackager.bat' :
'launchPackager.command';
const packagerDir = path.resolve(__dirname, '..', '..', 'packager');
const launchPackagerScript = path.resolve(packagerDir, scriptFile);
const procConfig = {cwd: packagerDir};
if (process.platform === 'darwin') {
if (yargV.open) {
return child_process.spawnSync('open', ['-a', yargV.open, launchPackagerScript], procConfig);
}
return child_process.spawnSync('open', [launchPackagerScript], procConfig);
} else if (process.platform === 'linux') {
procConfig.detached = true;
if (yargV.open){
return child_process.spawn(yargV.open,['-e', 'sh', launchPackagerScript], procConfig);
}
return child_process.spawn('sh', [launchPackagerScript], procConfig);
} else if (/^win/.test(process.platform)) {
procConfig.detached = true;
procConfig.stdio = 'ignore';
return child_process.spawn('cmd.exe', ['/C', launchPackagerScript], procConfig);
} else {
console.log(chalk.red(`Cannot start the packager. Unknown platform ${process.platform}`));
}
}
module.exports = {
name: 'run-android',
description: 'builds your app and starts it on a connected Android emulator or device',
func: runAndroid,
options: [{
command: '--install-debug',
}, {
command: '--root [string]',
description: 'Override the root directory for the android build (which contains the android directory)',
default: '',
}, {
command: '--flavor [string]',
description: '--flavor has been deprecated. Use --variant instead',
}, {
command: '--variant [string]',
}, {
command: '--appFolder [string]',
description: 'Specify a different application folder name for the android source.',
default: 'app',
}, {
command: '--appIdSuffix [string]',
description: 'Specify an applicationIdSuffix to launch after build.',
default: '',
}, {
command: '--main-activity [string]',
description: 'Name of the activity to start',
default: 'MainActivity',
}, {
command: '--deviceId [string]',
description: 'builds your app and starts it on a specific device/simulator with the ' +
'given device id (listed by running "adb devices" on the command line).',
}, {
command: '--no-packager',
description: 'Do not launch packager while building',
}],
};
They are just in the /node_modules/react-native
I am able to run tests locally on my remote selenium server and they run just fine.
When I go to run them on my Jenkins box on the same remote selenium server in Jenkins I am getting No Specs found, and in the output of my selenium server I am seeing the following:
21:33:41.256 INFO - Executing: [execute async script: try { return (function (attempts, ng12Hybrid, asyncCallback) {
var callback = function(args) {
setTimeout(function() {
asyncCallback(args);
}, 0);
};
var check = function(n) {
try {
if (!ng12Hybrid && window.getAllAngularTestabilities) {
callback({ver: 2});
} else if (window.angular && window.angular.resumeBootstrap) {
callback({ver: 1});
} else if (n < 1) {
if (window.angular) {
callback({message: 'angular never provided resumeBootstrap'});
} else {
callback({message: 'retries looking for angular exceeded'});
}
} else {
window.setTimeout(function() {check(n - 1);}, 1000);
}
} catch (e) {
callback({message: e});
}
};
check(attempts);
}).apply(this, arguments); }
catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [10, false]])
21:33:41.273 INFO - Done: [execute async script: try { return (function (attempts, ng12Hybrid, asyncCallback) {
var callback = function(args) {
setTimeout(function() {
asyncCallback(args);
}, 0);
};
var check = function(n) {
try {
if (!ng12Hybrid && window.getAllAngularTestabilities) {
callback({ver: 2});
} else if (window.angular && window.angular.resumeBootstrap) {
callback({ver: 1});
} else if (n < 1) {
if (window.angular) {
callback({message: 'angular never provided resumeBootstrap'});
} else {
callback({message: 'retries looking for angular exceeded'});
}
} else {
window.setTimeout(function() {check(n - 1);}, 1000);
}
} catch (e) {
callback({message: e});
}
};
check(attempts);
}).apply(this, arguments); }
catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [10, false]]
21:33:41.288 INFO - Executing: [execute script: return (function (trackOutstandingTimeouts) {
var ngMod = angular.module('protractorBaseModule_', []).config([
'$compileProvider',
function($compileProvider) {
if ($compileProvider.debugInfoEnabled) {
$compileProvider.debugInfoEnabled(true);
}
}
]);
if (trackOutstandingTimeouts) {
ngMod.config([
'$provide',
function ($provide) {
$provide.decorator('$timeout', [
'$delegate',
function ($delegate) {
var $timeout = $delegate;
var taskId = 0;
if (!window['NG_PENDING_TIMEOUTS']) {
window['NG_PENDING_TIMEOUTS'] = {};
}
var extendedTimeout= function() {
var args = Array.prototype.slice.call(arguments);
if (typeof(args[0]) !== 'function') {
return $timeout.apply(null, args);
}
taskId++;
var fn = args[0];
window['NG_PENDING_TIMEOUTS'][taskId] =
fn.toString();
var wrappedFn = (function(taskId_) {
return function() {
delete window['NG_PENDING_TIMEOUTS'][taskId_];
return fn.apply(null, arguments);
};
})(taskId);
args[0] = wrappedFn;
var promise = $timeout.apply(null, args);
promise.ptorTaskId_ = taskId;
return promise;
};
extendedTimeout.cancel = function() {
var taskId_ = arguments[0] && arguments[0].ptorTaskId_;
if (taskId_) {
delete window['NG_PENDING_TIMEOUTS'][taskId_];
}
return $timeout.cancel.apply($timeout, arguments);
};
return extendedTimeout;
}
]);
}
]);
}
}).apply(null, arguments);, [true]])
21:33:41.312 INFO - Done: [execute script: return (function (trackOutstandingTimeouts) {
var ngMod = angular.module('protractorBaseModule_', []).config([
'$compileProvider',
function($compileProvider) {
if ($compileProvider.debugInfoEnabled) {
$compileProvider.debugInfoEnabled(true);
}
}
]);
if (trackOutstandingTimeouts) {
ngMod.config([
'$provide',
function ($provide) {
$provide.decorator('$timeout', [
'$delegate',
function ($delegate) {
var $timeout = $delegate;
var taskId = 0;
if (!window['NG_PENDING_TIMEOUTS']) {
window['NG_PENDING_TIMEOUTS'] = {};
}
var extendedTimeout= function() {
var args = Array.prototype.slice.call(arguments);
if (typeof(args[0]) !== 'function') {
return $timeout.apply(null, args);
}
taskId++;
var fn = args[0];
window['NG_PENDING_TIMEOUTS'][taskId] =
fn.toString();
var wrappedFn = (function(taskId_) {
return function() {
delete window['NG_PENDING_TIMEOUTS'][taskId_];
return fn.apply(null, arguments);
};
})(taskId);
args[0] = wrappedFn;
var promise = $timeout.apply(null, args);
promise.ptorTaskId_ = taskId;
return promise;
};
extendedTimeout.cancel = function() {
var taskId_ = arguments[0] && arguments[0].ptorTaskId_;
if (taskId_) {
delete window['NG_PENDING_TIMEOUTS'][taskId_];
}
return $timeout.cancel.apply($timeout, arguments);
};
return extendedTimeout;
}
]);
}
]);
}
}).apply(null, arguments);, [true]]
Like I said, these run just fine locally, so I am not sure what is going on with my Jenkins machine.
Here is my protractor config file:
// Configuration constants
var downloadsFolder = 'test/downloads/',
today = ("0" + (new Date()).getDate()).slice(-2),
month = ("0" + ((new Date()).getMonth() + 1)).slice(-2),
baseUrl = 'BASE URL GOES HERE';
// Test report setup w/ screenshot
var HtmlScreenshotReporter = require('protractor-jasmine2-screenshot-reporter');
var reporter = new HtmlScreenshotReporter({
dest: 'test/report',
filename: 'e2e-report.html'
});
// Protractor config
exports.config = {
suites: {
explore: '.protractor/src/app/exploration/tests/exploration.scenario.js',
login: '.protractor/src/auth-app/login/tests/login.scenario.js',
stories: '.protractor/src/app/story/tests/story.scenario.js',
cohorts: '.protractor/src/app/cohort/tests/cohort.scenario.js',
visualize: '.protractor/src/app/visualize/tests/visualize.scenario.js'
},
baseUrl: 'BASE URL GOES HERE',
directConnect: false,
// Override default 11s timeout for long requests such as visualize's "Recommended Visualizations"
// See https://github.com/angular/protractor/blob/master/docs/timeouts.md
allScriptsTimeout: 25 * 1000,
jasmineNodeOpts: {
defaultTimeoutInterval: 90 * 1000
},
multiCapabilities: [
{
browserName: 'chrome',
seleniumAddress: "http://SELENIUM SERVER URL HERE:4444/wd/hub",
platform: 'ANY',
version: 'ANY',
chromeOptions: {
args: ['--no-sandbox', '--test-type=browser', '--lang=en', '--start-maximized'],
prefs: {
download: {
prompt_for_download: false,
directory_upgrade: true,
default_directory: 'test/downloads'
},
},
}
// shardTestFiles: true,
// maxInstances: 2
}
],
onPrepare: function() {
// Set browser window size
browser.driver.manage().window().maximize();
//Setup screenshots
jasmine.getEnv().addReporter(reporter);
browser.get('BASE URL GOES HERE');
},
// Setup the report before any tests start
beforeLaunch: function() {
return new Promise(function(resolve){
reporter.beforeLaunch(resolve);
});
},
// Close the report after all tests finish
afterLaunch: function(exitCode) {
return new Promise(function(resolve){
reporter.afterLaunch(resolve.bind(this, exitCode));
});
},
params: {
baseUrl: baseUrl,
downloadsFolder: 'test/downloads',
cohort: {
listView: baseUrl + 'cohorts',
newView: baseUrl + 'cohorts/new'
},
story: {
listView: baseUrl + 'stories',
newView: baseUrl + 'story/new',
displayView: baseUrl + 'story'
},
visualize: {
listView: baseUrl + 'visualize',
newView: baseUrl + 'visualize/new'
},
explore: {
listView: baseUrl + 'explorations',
newView: baseUrl + 'explorations/new',
excelFilename: downloadsFolder + `DataExport_2016-${month}-${today}.xlsx`,
csvFilename: downloadsFolder + `DataExport_2016-${month}-${today}.csv`,
maxDownloadTime: 10 * 1000
}
}
};
This boiled down to a permissions issue. Once I added my jenkins user to sudo I was able to do a make command on the project which built all of the necessary files and which also converted my typescript tests over to Javascript and allowed them to run.
been working with visual studio code and I am trying to use the built debugger. I have found examples and have tried to set it up. I have successfully got the gulp serve task setup and it runs correctly with the command
⇧⌘B
not the actual play button in the debugger tab. The examples I have found for debugging with the chrome extension does not include grunt or gulp automated tasks. Is it possible to use the gulp tasks and the debugger?
launch.json
{
"version": "0.2.0",
"configurations": [
{
"request": "launch",
// Name of configuration; appears in the launch configuration drop down menu.
"name": "node gulp.js ..",
// Type of configuration. Possible values: "node", "mono".
"type": "node",
// Workspace relative or absolute path to the program.
"program": "${workspaceRoot}./node_modules/gulp/bin/gulp.js",
// Automatically stop program after launch.
"stopOnEntry": true,
// Command line arguments passed to the program.
"args": [
"--extensionDevelopmentPath=${workspaceRoot}"
],
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
"cwd": "${workspaceRoot}.",
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
"runtimeExecutable": "${execPath}",
// Optional arguments passed to the runtime executable.
"runtimeArgs": [],
// Environment variables passed to the program.
"env": {},
// Use JavaScript source maps (if they exist).
"sourceMaps": false,
// If JavaScript source maps are enabled, the generated code is expected in this directory.
"outDir": "${workspaceRoot}out"
}
]
}
tasks.json
{
// See http://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "gulp",
"isShellCommand": true,
"args": [
"--no-color"
],
"tasks": [
{
"taskName": "serve",
"args": [],
"isBuildCommand": true,
"isWatching": true,
"problemMatcher": [
"$lessCompile",
"$tsc",
"$jshint"
]
}
]
}
gulp.config.js
module.exports = function($, usehtml) {
// distribution folder
var dist = 'app/';
var source = 'src/'; // for abs path construction
var markupEngine = usehtml ? 'html' : 'jade';
var markupExt = '.' + markupEngine;
// main source folders
var srcLESS = source + 'less/';
var srcSCSS = source + 'scss/';
var srcHTML = source + markupEngine + '/';
var srcJS = source + 'js/';
// Shared config object
var config = {
// ---
// Paths
// ---
dist: dist,
distCSS: dist + 'css',
distJS: dist + 'js',
source: source,
srcLESS: srcLESS,
srcSCSS: srcSCSS,
srcHTML: srcHTML,
srcJS: srcJS,
html: {
index: [srcHTML + 'index' + markupExt],
views: [
srcHTML + '**/*' + markupExt,
'!'+srcHTML + 'index' + markupExt
],
templates: [
srcHTML + 'views/sidebar/*' + markupExt,
srcHTML + 'views/navbar/*' + markupExt,
srcHTML + 'views/layers/*' + markupExt,
srcHTML + 'views/filters/*' + markupExt,
srcHTML + 'views/modals/*' + markupExt
],
all: [srcHTML + '**/*' + markupExt]
},
less: {
styles: [srcLESS + 'styles.less'],
watch: [srcLESS + 'app/**/*.less'],
bootstrap: [srcLESS + 'bootstrap/bootstrap.less']
},
scss: {
styles: [srcSCSS + 'styles.scss'],
watch: [srcSCSS + 'app/**/*.scss'],
bootstrap: [srcSCSS + 'bootstrap.scss']
},
js: [srcJS + 'app.module.js', srcJS + 'modules/**/*.js', srcJS + 'custom/**/*.js'],
// ---
// Plugins
// ---
plato: {
js: srcJS + '**/*.js'
},
report: './report/',
tplcache: {
file: 'templates.js',
opts: {
standalone: false,
root: 'templates',
module: 'insight'
}
},
webserver: {
webroot: '.',
host: 'localhost',
port: '3000',
livereload: true,
directoryListing: false
},
prettify: {
indent_char: ' ',
indent_size: 3,
unformatted: ['a', 'sub', 'sup', 'b', 'i', 'u']
},
usemin: {
path: '.',
css: [$.minifyCss({ processImport: false }), 'concat', $.rev()],
// html: [$.minifyHtml({empty: true})],
vendor: [$.uglify( {preserveComments:'some'} ), $.rev()],
js: [$.ngAnnotate(), $.uglify( {preserveComments:'some'} ), $.rev()]
}
};
// scripts to check with jshint
config.lintJs = [].concat(config.js, config.distJS);
return config;
};
gulpfile.js
var argv = require('yargs').argv;
var usehtml = true;
var usertl = argv.usertl;
var usescss = argv.usescss;
var gulp = require('gulp'),
$ = require('gulp-load-plugins')(),
gutil = require('gulp-util'),
gulpsync = require('gulp-sync')(gulp),
path = require('path'),
glob = require('glob'),
del = require('del'),
runSequence = require('run-sequence'),
config = require('./gulp.config')($, usehtml);
// production mode
var isProduction = false;
//---------------
// TASKS
//---------------
// APP LESS
gulp.task('styles', function () {
log('Compiling styles to CSS..');
var stylesSrc = usescss ? config.scss.styles : config.less.styles;
return gulp.src(stylesSrc)
.pipe(isProduction ? gutil.noop() : $.sourcemaps.init())
.pipe(usescss ? $.sass() : $.less())
.on("error", handleError)
.pipe($.if(usertl, $.rtlcss()))
.pipe(isProduction ? $.minifyCss({processImport: false}) : gutil.noop())
.pipe(isProduction ? gutil.noop() : $.sourcemaps.write())
.pipe(gulp.dest(config.distCSS));
});
// BOOSTRAP
gulp.task('bootstrap', function () {
log('Compiling Bootstrap..');
var bsSrc = usescss ? config.scss.bootstrap : config.less.bootstrap;
return gulp.src(bsSrc)
.pipe(isProduction ? gutil.noop() : $.sourcemaps.init())
.pipe(usescss ? $.sass() : $.less())
.on("error", handleError)
.pipe($.if(usertl, $.rtlcss()))
.pipe(isProduction ? $.minifyCss({processImport: false}) : gutil.noop())
.pipe(isProduction ? gutil.noop() : $.sourcemaps.write())
.pipe(gulp.dest(config.distCSS));
});
// HTML
gulp.task('markup', ['index', 'views']);
gulp.task('views', buildMarkup(config.html.views, config.dist));
gulp.task('index', ['templatecache'], buildMarkup(config.html.index, '.', false, true));
gulp.task('templatecache', ['clean-scripts'], buildMarkup(config.html.templates, config.dist + 'js', true));
// SERVER
// -----------------------------------
gulp.task('webserver', function () {
log('Starting web server.. ');
return gulp.src(config.webserver.webroot)
.pipe($.webserver(config.webserver));
});
//---------------
// WATCH
//---------------
// Rerun the task when a file changes
gulp.task('watch', function () {
log('Starting watch with live reload ...');
$.livereload.listen();
if (usescss) gulp.watch([config.scss.watch, config.scss.styles], ['styles']);
else gulp.watch([config.less.watch, config.less.styles], ['styles']);
if (usescss) gulp.watch(config.scss.bootstrap, ['bootstrap']);
else gulp.watch(config.less.bootstrap, ['bootstrap']);
gulp.watch(config.html.all, ['markup']);
gulp.watch(config.html.templates, ['templatecache']);
gulp
.watch([].concat(config.less.watch, config.html.views, config.html.templates, config.js))
.on('change', function (event) {
setTimeout(function () {
$.livereload.changed(event.path);
}, 1400);
});
});
/**
* Clean
*/
gulp.task('clean', ['clean-scripts', 'clean-styles', 'clean-markup']);
gulp.task('clean-scripts', function (cb) {
var js = config.distJS + '/*{js,map}';
clean(js, cb);
});
gulp.task('clean-styles', function (cb) {
var css = config.distCSS + '/*{css,map}';
clean(css, cb);
});
gulp.task('clean-markup', function (cb) {
var html = ['index.html', config.dist + 'views/'];
clean(html, cb);
});
gulp.task('clean-build', function (cb) {
log('Removing development assets');
var delFiles = [
config.distJS + '/' + config.tplcache.file,
config.distCSS + '/bootstrap.css',
config.distCSS + '/styles.css'
];
clean(delFiles, cb);
});
/**
* vet the code and create coverage report
*/
gulp.task('lint', function () {
log('Analyzing source with JSHint');
return gulp
.src(config.lintJs)
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish', {verbose: true}))
.pipe($.jshint.reporter('fail'));
});
//---------------
// Visualizer report
//---------------
gulp.task('plato', function (done) {
log('Analyzing source with Plato');
log('Browse to /report/plato/index.html to see Plato results');
startPlatoVisualizer(done);
});
//---------------
// MAIN TASKS
//---------------
// build for production
gulp.task('build', [], function (cb) {
runSequence('clean', 'production', 'compile', 'clean-build', cb);
});
gulp.task('production', function () {
isProduction = true;
});
// default (no minify, sourcemaps and watch)
gulp.task('default', function (callback) {
runSequence('clean', 'compile', 'watch', 'done', callback);
}).task('done', done);
// serve development by default
gulp.task('serve', function (cb) {
runSequence('default', 'webserver', cb);
});
// optional serve production
gulp.task('serve-build', function (cb) {
runSequence('build', 'webserver', cb);
});
// run tasks without watch
gulp.task('compile', function (cb) {
runSequence(
'bootstrap',
'styles',
'templatecache',
'markup',
cb);
});
/////////////////
/**
* Error handler
*/
function handleError(err) {
console.log(err.toString());
this.emit('end');
}
/**
* Build html templates
* #param {string} src source files folder
* #param {string} dst target folder
* #param {boolean} useTplcache Should generate angular template cache
* #return {stream}
*/
function buildMarkup(src, dst, useTplcache, useMin) {
return function () {
log('Compiling HTML...');
if (useTplcache) log('Creating AngularJS templateCache..');
return gulp.src(src)
.pipe(isProduction ? gutil.noop() : $.changed(dst, {extension: '.html'}))
.pipe($.if(!usehtml, $.jade({
locals: {
scripts: glob.sync(config.source + 'js/**/*.js')
}
})
)
)
.on("error", handleError)
.pipe($.htmlPrettify(config.prettify))
// .pipe($.angularHtmlify())
.pipe(isProduction && useMin ?
$.usemin(config.usemin)
: gutil.noop()
)
.pipe(useTplcache ?
$.angularTemplatecache(config.tplcache.file, config.tplcache.opts)
: gutil.noop()
)
.pipe(gulp.dest(dst))
;
}
}
/**
* Delete all files in a given path
* #param {Array} path - array of paths to delete
* #param {Function} done - callback when complete
*/
function clean(path, done) {
log('Cleaning: ' + $.util.colors.blue(path));
del(path, done);
}
/**
* Start Plato inspector and visualizer
*/
function startPlatoVisualizer(done) {
log('Running Plato');
var files = glob.sync(config.plato.js);
var excludeFiles = /.*\.spec\.js/;
var plato = require('plato');
var options = {
title: 'Plato Inspections Report',
exclude: excludeFiles
};
var outputDir = config.report + 'plato/';
plato.inspect(files, outputDir, options, platoCompleted);
function platoCompleted(report) {
var overview = plato.getOverviewReport(report);
log(overview.summary);
if (done) {
done();
}
}
}
/**
* Just to be polite :)
*/
function done() {
setTimeout(function () { // it's more clear to show msg after all
log('Done.. Watching code and reloading on changes..');
}, 500);
};
/**
* Standard log
*/
function log(msg) {
var prefix = '*** ';
gutil.log(prefix + msg);
}
It seems there are multiple errors in your launch config.
Some of the paths in your config are wrong. for example:
"${workspaceRoot}./node_modules/gulp/bin/gulp.js"
should be
"${workspaceRoot}/node_modules/gulp/bin/gulp.js"
${workspaceRoot} is a placeholder for the absolute path to your workspace. You cannot use relative path syntax like ./[relativepath] in launch.json. just replace . with ${workspaceRoot}.
If you are using "type": "node" in your launch config "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js" should point to the index file of your node application and not to the gulp executable.
In your gulp file it looks like you are trying to debug a website. In this case you should use Debugger for Chrome or Debugger for Edge vscode extension