Create shim for ember-cli - ember-cli

I am trying to create shim for getstream library for ember-cli as #jmurphyau answered here.
I bower install getstream, then create file
vendor/shims/getstream.js
(function() {
/* globals define, getstream */
function getstreamModule() {
'use strict';
return getstream; // <-- got error here
}
define('getstream', [], getstreamModule);
})();
and add lines to Brocfile.js
app.import('bower_components/getstream/dist/js_min/getstream.js');
app.import('vendor/shims/getstream.js', {
exports: {
'getstream': [ 'default' ]
}
});
and try to import Stream from 'getstream'; in route.
Got Uncaught ReferenceError: getstream is not defined in getstream.js
What's going wrong and how it could be fixed? Thanks for answers.

Have you tried using ember-browsify?
That library doesn't look like it exposes a global variable called getstream which is why your getting that error.
It does however look like it supports CommonJS module syntax so ember-browserify should work.
Install ember-browserify
ember install ember-browserify
Install the CommonJS library as an NPM package
npm install --save-dev getstream
Use the NPM package with regular import syntax
import getstream from 'npm:getstream';

Related

Unit testing ionic services with jest

I'm building an ionic app and would like to add unit tests for a couple of services. I'm trying to get jest working with typescript but it doesn't seem to play well.
I'm getting this error:
/myuser/project/node_modules/#ionic/storage/dist/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { NgModule } from '#angular/core';
^^^^^^
SyntaxError: Unexpected token import
Now I have read that you have to add the babel-plugin-transform-es2015-modules-commonjs and use that in the test env of babel. However I am using babel 7 and this plugin is not available for babel 7. Is there a different solution?
I will also provide my package.json and .babelrc below.
gist
You just need to add #ionic/storage to your transformIgnorePatterns in jest config. For example, here's mine, take note of the #ionic/storage part:
"transformIgnorePatterns": [
"node_modules/(?!#ngrx|moment|#ionic/storage|#ionic-native)"
]
Additionally, make sure in your tsconfig compiler options you have module: 'commonjs'
Also, if you need localstorage mocks, you can just use the following npm module:
npm install --save-dev jest-localstorage-mock
and then (in your setupJest.ts file)
import 'jest-localstorage-mock
Lastly, I recommend taking a look at:
https://github.com/thymikee/jest-preset-angular
for more help with jest + ionic configurations.

import with jest error: Unexpected token import

I've seen similar questions but still can't find a viable solution.
I'm trying to integrate Jest into a working project, which uses import/export default in hundreds of places. The following test does work for Jest using require:
const bar = require('../../flows/foo');
test('adds 1 + 2 to equal 3', () => {
expect(bar.foobar(1, 2)).toBe(3);
});
when export is:
module.exports = {
foobar: foobar,
fizz: fizz
}
The functions I'll want to be testing however are exported using:
export default {
foobar: foobar,
fizz: fizz
};
So when I try to update my test to import:
import foobar from '../../flows/foo';
With export:
export default {foobar: foobar};
I get the error
SyntaxError: Unexpected token import
All it takes:
// run this command (or npm equivalent)
yarn add #babel/core #babel/preset-env
// add babel.config.js
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current'
}
}
]
]
};
Jest automatically picks it up, no other configuration required.
You have not set up a .babelrc file in your project, so transpiling is not happening. You need to transpile the ES6+ syntax (import, export, etc) into browser readable ES5.
I ran into this and solved it this way thanks to this GitHub issue post:
If you're using babel to transpile your code then remember to use the transform-es2015-modules-commonjs plugin.
To use it, you'll need to:
Install the plugin for BabelJS by entering this command in the CLI:
npm install --save-dev babel-plugin-transform-es2015-modules-commonjs
Add the plugin to your list of plugins in your babel config
plugins: [
"transform-es2015-modules-commonjs"
]

How to use blueimp-file-upload with webpack?

I'm using blueimp-file-upload in my website, and I'm using webpack to organize my js code.
I installed blueimp-file-upload and jquery.ui.widget from NPM
npm install --save blueimp-file-upload
npm install --save jquery.ui.widget
and I require blueimp-file-upload in my entry file
require('blueimp-file-upload')
but when I run webpack, I get thie error:
ERROR in ./~/blueimp-file-upload/js/jquery.fileupload.js
Module not found: Error: Cannot resolve module 'jquery.ui.widget' in E:\app-parent\cooka-common-web\src\main\resources\static\node_modules\blueimp-file-upload\js
# ./~/blueimp-file-upload/js/jquery.fileupload.js 19:8-22:19
If you're working with images:
Webpack was complaining about some modules that weren't in the blueimp-file-upload package. Here is the way I got this working:
Install missing dependencies:
npm i -S blueimp-load-image
npm i -S blueimp-canvas-to-blob
Configure Webpack:
config.resolve = {
extensions: ['', '.js'],
alias: {
'load-image': 'blueimp-load-image/js/load-image.js',
'load-image-meta': 'blueimp-load-image/js/load-image-meta.js',
'load-image-exif': 'blueimp-load-image/js/load-image-exif.js',
'canvas-to-blob': 'blueimp-canvas-to-blob/js/canvas-to-blob.js',
'jquery-ui/widget': 'blueimp-file-upload/js/vendor/jquery.ui.widget.js'
}
};
Include scripts in your app:
import "blueimp-file-upload/js/vendor/jquery.ui.widget.js";
import "blueimp-file-upload/js/jquery.iframe-transport.js";
import "blueimp-file-upload/js/jquery.fileupload.js";
import "blueimp-file-upload/js/jquery.fileupload-image.js";
Disable both AMD and CommonJS and use the Browser Global jQuery.
/* The jQuery UI widget factory, can be omitted if jQuery UI is already included */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/vendor/jquery.ui.widget.js');
/* The Iframe Transport is required for browsers without support for XHR file uploads */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.iframe-transport.js');
/* The basic File Upload plugin */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload.js');
/* The File Upload processing plugin */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload-process.js');
/* The File Upload validation plugin */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload-validate.js');
/* The File Upload Angular JS module */
require('imports?define=>false&exports=>false!blueimp-file-upload/js/jquery.fileupload-angular.js');
This is the configuration I'm using to integrate webpack, blueimp-fileupload with angular. Alternatively you can configure in your webpack.config.js as a regex to avoid repeating loaders.
resolve: {
extensions: ['', '.js'],
alias: {
'jquery-ui/widget': 'blueimp-file-upload/js/vendor/jquery.ui.widget.js'
}
}
I had almost identical problem, except that Error announced not 'jquery.ui.widget' but 'jquery/ui/widget'.
For me #Gowrav answer was wrong way.
After days of straying I've solved it in the simple way. Just did:
npm install jquery-ui
The fact is that jquery.fileupload.js searching for its vendor:
But in context where jquery.fileupload.js is trying to import dependency, of course, it can't be found (resolved). So I add it to project instead.
P.S. It's just my opinion about how does all work. But this way has helped me.
jquery.fileupload.js checks for AMD require first which results in this error. You can teach webpack not to use AMD style for this file. (Make sure to npm install imports-loader for this method to work.):
require('imports?define=>false!blueimp-file-upload')
It should correctly register the module as CommonJS and will require the jquery.ui.widget from the right location.
Read more here: http://webpack.github.io/docs/shimming-modules.html#disable-some-module-styles
You can add an alias to jquery.ui.widget's main file - it unfortunately doesn't specify one in its package.json, so webpack can't find it otherwise.
resolve: {
alias: {
"jquery.ui.widget": "node_modules/jquery.ui.widget/jquery.ui.widget.js"
}
},
first install two plugins
npm i blueimp-file-upload --save
npm i jquery-ui --save
then require in web pack
require('blueimp-file-upload/js/jquery.fileupload')
actually you can solve this by changing your webpack config, just add the path to resolve (for example I am using bower)
resolve: {
extensions: [ '', '.js', '.jsx' ],
modulesDirectories: [
'node_modules',
'bower_components',
'bower_components/blueimp-file-upload/js/vendor'
]
}
In webpack 3.x, the syntax will look like this:
{
test: require.resolve("blueimp-file-upload"),
use: "imports-loader?define=>false"
}

How can I setup webpack to minify and combine scss and javascript like CodeKit?

I'm having trouble using webpack instead of Codekit v1.9.3. I started working to move from CodeKit to Grunt and Gulp, and then learned about webpack which sounds very cool. I just can't seem to get it working correctly.
"Like Codekit" means I can:
Write javascript with the coffeescript syntax
Have all script source files and libraries minified / uglified and combined into one file
Selectively include components of the bootstrap-sass (scss) framework as needed
Maintain a small file with bootstrap customizations via sass variables, like $brand-primary
Use webpack --watch to compile both scripts and styles automatically when they are changed
End up with one css file and one script file that can be included with a stylesheet and script tag.
Codekit Project Setup
Bower resources:
I'm currently storing these globally, outside of the project:
~/bower_components/twbs-bootstrap-sass/vendor/assets/stylesheets
Because CodeKit supports compass, I've got this in my config.rb file:
add_import_path "~/bower_components/twbs-bootstrap-sass/vendor/assets/stylesheets"
Project Structure
js/fancybox.js
js/main.js <-- currently the compiled js 'output' file
js/main.coffee
css/styles.css <-- currently the compiled css 'output' file
scss/styles.scss
scss/modules/_bootstrap-customizations.scss
scss/modules/_typography.scss
scss/partials/_header.scss
scss/partials/_footer.scss
Contents of styles.scss
#import "modules/bootstrap-customizations"; # local customizations
#import "bootstrap/variables";
#import "bootstrap/mixins";
... # load bootstrap files as required
#import "bootstrap/wells";
System Setup:
system: OS X 10.9
node - v0.10.32
npm - v2.1.7
zsh - zsh 5.0.7 (x86_64-apple-darwin13.4.0)
node was installed with homebrew's brew install node and seems to be working fine otherwise.
What I've Tried
I've read over these pages:
http://webpack.github.io/docs/configuration.html
https://github.com/petehunt/webpack-howto
http://webpack.github.io/docs/tutorials/getting-started/
https://www.npmjs.org/package/bootstrap-sass-webpack
I've attempted to create a webpack.config.js file several times, my latest attempt was several versions of this:
module.exports = {
entry: [
"./node_modules/bootstrap-sass-webpack!./bootstrap-sass.config.js",
"./js/main.coffee"
],
output: {
path: __dirname,
filename: "main.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
};
Webpack Error
When I run webpack I get this:
ERROR in ./~/bootstrap-sass-webpack/~/css-loader!/Users/cwd/~/sass-loader!./~/bootstrap-sass-webpack/bootstrap-sass-styles.loader.js!./bootstrap-sass.config.js
stdin:1: file to import not found or unreadable: "~bootstrap-sass/assets/stylesheets/bootstrap/variables
NPM Error
I get an error when attempting to npm install bootstrap-sass, and not had any luck when searching for a solution. I'm not even sure I need this module.
npm ERR! Darwin 13.4.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "bootstrap-sass"
npm ERR! node v0.10.32
npm ERR! npm v2.1.7
npm ERR! code EPEERINVALID
npm ERR! peerinvalid The package bootstrap-sass does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer bootstrap-sass-webpack#0.0.3 wants bootstrap-sass#~3.2.0
npm ERR! Please include the following file with any support request:
npm ERR! /Users/cwd/webpack-test/npm-debug.log
Sources of Confusion
The most confusing parts of webpack for me are:
Where should things like require("bootstrap-sass-webpack") be added - is it in the webpack.config.js file, or in the js/main.js file?
Should modules like this available to webpack as soon as they are installed with npm install ?
I thought that I should do npm install webpack -g so that webpack was installed globally, and use npm install without the -g for the other modules. However, I don't see any node_modules folder being created in my project. Shouldn't there be one?
How are the search paths determined / specified for things like require("bootstrap-sass-webpack") ?
What node modules should I install to be able to do this? And what should my webpack.config.js look like?
Introduction
Webpack is mainly a JavaScript-bundler. Its "native" language is JavaScript and every other source requires a loader which transforms it to JavaScript. If you require() an html-file for example...
var template = require("./some-template.html");
...you'll need the html-loader. It turns...
<div>
<img src="./assets/img.png">
</div>
...into...
module.exports = "<div>\n <img src=\"" + require("./assets/img.png") + "\">\n</div>";
If a loader doesn't return JavaScript, it needs to be "piped" to another loader.
How to load SASS-files
Configure loaders
In order to use SASS you'll need at least the sass-loader and the css-loader. The css-loader returns a JavaScript string. If you want to import the returned JavaScript string as StyleSheet, you'll also need the style-loader.
Run npm i sass-loader css-loader style-loader --save
Now you need to apply these loaders on all files that match /\.scss$/:
// webpack.config.js
...
module: {
loaders: [
// the loaders will be applied from right to left
{ test: /\.scss$/, loader: "style!css!sass" }
]
}
...
You can also pass options to node-sass as query parameters:
{
test: /\.scss$/, loader: "style!css!sass?includePaths[]=" +
path.resolve(__dirname, "./bower_components/bootstrap-sass/assets/stylesheets/"
}
Since bootstrap references icons via the url() statement, the css-loader will try to include these assets into the bundle and will throw an exception otherwise. That's why you'll also need the file-loader:
// webpack.config.js
...
module: {
loaders: [
{ test: /\.scss$/, loader: "style!css!sass" },
{ test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/, loader: "file" },
]
}
...
Configure entry
To include bootstrap into your bundle there are several ways. One is via the multi-entry option as you've already tried. I recommend to use a single entry where you require() your main sass-file:
// main.js
require("./main.scss");
Given that your includePaths are configured then you can do:
// main.scss
// Set the font path so that url() points to the actual file
$icon-font-path: "../../../fonts/bootstrap";
#import "bootstrap";
Please note that import statements inside scss-files are not touched by webpack because libsass has no api (yet) to provide custom resolvers.
To prevent code duplication it's also important to have a single main sass-file, because webpack compiles every sass-file individually.
With the coffee-loader installed via npm your final webpack.config.js should look like:
module.exports = {
entry: "./js/main.coffee",
output: {
path: __dirname,
filename: "main.js"
},
module: {
loaders: [
{ test: /\.scss$/, loader: "style!css!sass" },
{ test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/, loader: "file" },
{ test: /\.coffee$/, loader: "coffee" }
]
}
};
Webpack globally?
It's best not to install webpack globally, because it's a dependency of your project and thus should be controlled via npm. You can use the scripts-section of your package.json:
{
...
"scripts": {
"start": "webpack --config path/to/webpack.config.js & node server.js"
}
}
Then you just need to run npm start

How to import an amd module in ember-cli?

I am building an EmberJS application with the great help of ember-cli, which is great, but I have an error and I cannot find what I am doing wrong.
Here is what I do in my broccoli file:
app.import('vendor/underscore/underscore.js', {
exports: {
"underscore": [
"underscore"
]
}
});
and then in one of my controllers:
import _ from "underscore";
ember-cli builds my application.
But when I go to the controller using underscore, I get the error:
Error: Could not find module underscore.
What am I doing wrong?
Try:
app.import({
development: 'vendor/underscore/underscore.js',
production: 'vendor/underscore/underscore.min.js'
}, {
'underscore': [
'default'
]
});
This will at least give "import _ from 'underscore';" a chance to work. If you choose an AMD or ES6 version of underscore/lodash, list which modules you wish to import with 'default'.
EDIT:
Is it crucial that you use underscore? Why I ask, I'm using lodash with one Ember-cli project, and it is working fine.
Console> bower install lodash --save
then in Brocfile:
app.import({
development: 'vendor/lodash/dist/lodash.js',
production: 'vendor/lodash/dist/lodash.min.js'
}, {
'lodash': [
'default'
]
});
//or:
app.import('vendor/lodash/dist/lodash.min.js');
As for underscore - there was an issue with devDependencies not being bundled, of which underscore is one.
I got this from locks on #emberjs IRC.
https://github.com/ef4/ember-browserify
In your project:
npm install --save-dev ember-browserify
npm install --save-dev underscore
In your controller:
import _ from "npm:underscore";
Then you can use _. For example: _.each([1,2,3], alert);. I took everything out I had manually added to brocfile and package.json. Apparently this will do it for you. Crazy!
In recent versions of ember (I am using 2.11) it is possible to load AMD in UMD wrappers using
app.import('bower_components/js-md5/js/md5.js', {using: [{
transformation: 'amd', as: 'js-md5'
}]});
And in your code
import md5 from 'js-md5';
In your case of underscore it should look like:
app.import('vendor/underscore/underscore.js', {using: [{
transformation: 'amd', as: 'underscore'
}]});