Is it possible to use brunch with ampersand? - ampersand

I am trying to use ampersand with brunch instead of browserify but it causes some problems.
Here is the code :
"use strict";
var View = require("ampersand-view");
var HelloView = View.extend({
autoRender: true,
template: '<p>Hello</p>'
});
var app = new HelloView();
document.body.appendChild(app.el);
brunch-config file has :
npm:
enabled: true
The brunch build command is OK but when I run the page in the browser I get :
View.extend is not a function
A console.log for the View object gives me a "function baseCopy()" object.
Is it not possible at all to use ampersand with brunch (without a browserify plugin) ?

Related

How to serve next js app using keystonejs?

I have a problem with serving next js app using keystonejs. I want to achive something similar like in to do nuxt example which you can choose while creating keystone project. I used code from this link https://www.keystonejs.com/keystonejs/app-next/ in index.js file, but I get an error while trying to run the app:
ReferenceError: distDir is not defined at Object.
What should I do?
this is what I have in my setup
create app folder (next js code)
create next.config.js in app folder
my next.js.config file has following code
const distDir = 'dist';
module.exports = {
distDir: `../${distDir}/www`,
env: {
SERVER_URL: process.env.SERVER_URL || 'http://localhost:4000',
},
publicRuntimeConfig: {
// Will be available on both server and client
// staticFolder: '/static',
},
};
it export the build artifacts in dist/www in root of keystone project.

Meteor : "console" variable undefined inside require call

I'm facing a strange problem on Meteor and I can't resolve it :
I'm developping a WebRTC app using Meteor, PeerJS and AdapterJS (which give an WebRTC plugin for unsupported browser like Safari or IE). These two libs are downloaded using NPM : meteor npm install peerjs/adapterjs
So in my view's controller I have :
view.js
//import Peer from 'peerjs'; => same error with "import"
//import AdapterJS from 'adapterjs';
Template.view.onRendered(function(){
AdapterJS = require("adapterjs");
Peer = require("peerjs");
//var peerkey="..."
var peer = new Peer({
key: peerkey, // get a free key at http://peerjs.com/peerserver
debug: 3,
config: {'iceServers': [
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'stun:stun1.l.google.com:19302' },
]}
});
But when I run my controller, I get an exception because "console" is undefined inside peerjs/util.js function when calling the peerjs constructor :
Uncaught TypeError: Cannot read property 'log' of undefined
Strangly, when I only require "peerjs", there is no exeption...
I tried to change the order of require functions but it won't work.
Other variable like "alert", "window.console" work and are defined inside the module but "console" not.. :/
Any suggestion can help ^^
Thanks in advance.
EDIT : If I add a breakpoint on the first line of node_module/peerjs/lib/util.js, I see that the "console" variable is "undefined" inside util.js but .... it is defined inside the caller function (fileEvaluate) !
EDIT2 : I tried something else to check if the code inside adapterjs redefine or change something : I put 'require("adapterjs")' inside a timeout function with a long delay (10 seconds) and .... console is still undefined inside peer module ! But when I comment require("adapterjs"), no error, console is defined ! I think that Meteor do something special before running the controller script depending on require functions...
EDIT3 : Here is a git repo to test the project : gitlab.com
If you display the dev console, you will see exceptions.
I found a solution, although I don't fully understand it myself. It's something to do with the way that Meteor imports modules, and Peerjs runs afoul of that.
Basically I copied node_modules/peerjs/dist/peer.js into the client directory, so that Meteor will load it "as is".
A small change to main.js as follows:
import './main.html';
// I placed peer.js from the node_modules/peerjs/dist/peer.js into the client folder and it works fine
// import {Peer} from 'peerjs';
import {AdapterJS as Adapter} from 'adapterjs';
Template.hello.onCreated(function helloOnCreated() {
// counter starts at 0
window.peer = new Peer({
and it works fine :)
I see in line 860+ of adapter.js that console is being defined (part of the shim) from https://github.com/Temasys/AdapterJS/blob/master/source/adapter.js
// IE 9 is not offering an implementation of console.log until you open a console
if (typeof console !== 'object' || typeof console.log !== 'function') {
/* jshint -W020 */
console = {} || console;
// Implemented based on console specs from MDN
// You may override these functions
console.log = function (arg) {};
console.info = function (arg) {};
console.error = function (arg) {};
This code defines the console if it doesn't find one to it's liking? Does this mean you are using IE9 or some other incompatible browser?
Try pasting this into your console and see what it tells you:
if (typeof console !== 'object' || typeof console.log !== 'function') alert("Console not present, needs to be shimmed?"); else console.log("console is ok");
Presumably the reason you are using adapter.js is for compatibility purposes - this will help you trouble shoot it. Please let me know what you find, as I will be following you down this path :)

Use autoprefixer synchronously

I want to use autoprefixer in my node application to compile css.
For my specific needs, I want to call autoprefixer without callback or promise.
Just plain:
var result = autoprefixer.process(css);
or
var result = myPrefixerWrap(css);
I am fighting with this for a while, can you help me please?
ps: I already tried postcss-js, but it result an json object for react use, and not pure css. For example {borderRadius:"5px"}
var prefixer = postcssJs.sync([ autoprefixer ]);
var cssCompiled = postcss.parse(css);
var cssObject = postcssJS.objectify(cssCompiled);
var autoResult = prefixer(cssObject);
PostCSS has an API for synchronously getting the results of Processor#process (process().css, aliased as toString()), which will work as long as all of the PostCSS plugins being used are synchronous (like Autoprefixer). The code to do that is as simple as:
var postcss = require('postcss'); // import postcss from 'posts';
var autoprefixer = require('autoprefixer'); // import autoprefixer from 'autoprefixer';
postcss([autoprefixer]).process(styleString).css;
Note: I had issues with using postcss-js in Webpack, so for those who see errors like:
Module parse failed: /path/to/node_modules/autoprefixer/node_modules/caniuse-db/features-json/css-regions.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
Or:
ERROR in ./~/autoprefixer/~/browserslist/index.js
Module not found: Error: Cannot resolve module 'fs' in /path/to/node_modules/autoprefixer/node_modules/browserslist
# ./~/autoprefixer/~/browserslist/index.js 3:14-27
Check out the Troubleshooting section of the postcss-js GitHub readme to find out what you need to add to your Webpack config to get it working.

how to resolve the 'unknown provider' angular injectr error when adding third party angular directives to angular-meteor app

I needed to add angular-file-upload directive to my meteor/angular app, which uses angular-meteor library.
I was able to find that package already converted as meteor smart package.
The installation instructions for this packege say:
"meteor add netanelgilad:angular-file-upload"
I did exactly that.
Now, that I start the app, I get
[$injector:unpr] Unknown provider: FileUploaderProvider <- FileUploader <- FileUploadController
Here is my controller, which uses that provider:
'use strict';
// FileUploadController controller
angular.module('socially').controller('FileUploadController',
['$scope', '$http', '$stateParams', '$location', 'FileUploader',
function($scope, $http, $stateParams, $location, FileUploader) {
$scope.uploadUrl = '';
var url = 'http://dctool-lnx.cloudapp.net:3001/api/files';
var uploader = $scope.uploader = new FileUploader({
});
}
]);
What can I do to make this provider recognized?
The resolution was: I forgot to add angularFileUpload as a dependancy to my angular app module.
Once added, the error went away.

Custom grunt plugin not playing nice with grunt-watch

I'm developing a custom grunt extension that reloads a chrome tab. It works fine when I use it within the plugin's own folder, but then when I try to download it from NPM and use it in another project, it goes bonkers.
I included it as such:
grunt.loadNpmTasks('grunt-chrome-extension-reload');
My custom task code, located in the tasks folder of the plugin, is as such:
/*
* grunt-chrome-extension-reload
* https://github.com/freedomflyer/grunt-chrome-extension-reload
*
* Copyright (c) 2014 Spencer Gardner
* Licensed under the MIT license.
*/
'use strict';
module.exports = function(grunt) {
var chromeExtensionTabId = 0;
grunt.initConfig({
/**
Reloads tab in chrome with id of chromeExtensionTabId
Called after correct tab number is found from chrome-cli binary.
*/
exec: {
reloadChromeTab: {
cmd: function() {
return chromeExtensionTabId ? "chrome-cli reload -t " + chromeExtensionTabId : "chrome-cli open chrome://extensions && chrome-cli reload";
}
}
},
/**
Executes "chrome-cli list tabs", grabs stdout, and finds open extension tabs ID's.
Sets variable chromeExtensionTabId to the first extension tab ID
*/
external_daemon: {
getExtensionTabId: {
options: {
verbose: true,
startCheck: function(stdout, stderr) {
// Find any open tab in Chrome that has the extensions page loaded, grab ID of tab
var extensionTabMatches = stdout.match(/\[\d{1,5}\] Extensions/);
if(extensionTabMatches){
var chromeExtensionTabIdContainer = extensionTabMatches[0].match(/\[\d{1,5}\]/)[0];
chromeExtensionTabId = chromeExtensionTabIdContainer.substr(1, chromeExtensionTabIdContainer.length - 2);
console.log("Chrome Extension Tab #: " + chromeExtensionTabId);
}
return true;
}
},
cmd: "chrome-cli",
args: ["list", "tabs"]
}
}
});
grunt.registerTask('chrome_extension_reload', function() {
grunt.task.run(['external_daemon:getExtensionTabId', 'exec:reloadChromeTab']);
});
};
So, when I run it in an external project with grunt watch, grunt spits out this error a few hundred times before quitting (endless loop?)
Running "watch" task
Waiting...Verifying property watch exists in config...ERROR
>> Unable to process task.
Warning: Required config property "watch" missing.
Fatal error: Maximum call stack size exceeded
Interestingly, can not even call my plugin within the watch task, and the problem persists. Only by removing grunt.loadNpmTasks('grunt-chrome-extension-reload'); can I get rid of the issue, which basically means that the code inside my task is wrong. Any ideas?
grunt.initConfig() is intended for end users. As it will completely erase any existing config (including your watch config) and replace with the config you're initializing. Thus when your plugin is ran it replaces the entire config with the exec and external_daemon task configs.
Try using grunt.config.set() instead. As it only sets a given part of the config rather than erasing the entire thing.
But a better pattern for a plugin is to let the user determine the config. Just have a plugin handle the task. In other words, avoid setting the config for the user.

Resources