How to get Source Maps with "stylify" and "insert-css" using Browserify / Gulp?
My gulp javascript task is like this:
gulp.task('js_watch', ['environmentCheck'], function()
{
var bundle = function()
{
return bundler.bundle()
.on('start', bundleLogger.start)
.on('error', handleErrors)
.pipe(source('bundle.js'))
// remove console.logs and such
.pipe(gulpif( global.ENV === 'production', streamify( strip() )))
// uglify JS and obfuscate in produciton mode only
.pipe(gulpif( global.ENV === 'production', streamify(uglify({ mangle: global.ENV === 'production' }))))
.pipe(print())
.pipe(gulp.dest(global.outputDir + datapaths.dataPath + '/js'))
.on('end', bundleLogger.end);
}
var browserify_instance = browserify({
// Required watchify args
cache: {}, packageCache: {}, fullPaths: true,
// Browserify Options
entries: ['./core/js/core.js'],
extensions: ['.jade', '.styl'],
debug: global.ENV === 'development'
});
browserify_instance.transform('stylify', {
use :[
jeet(),
rupture(),
typographic(),
axis(),
autoprefixer({ browsers: ['ie 7', 'ie 8'] })
],
sourcemap: { inline: global.ENV === 'development' },
compress: global.ENV === 'production',
});
var bundler = watchify(browserify_instance);
bundler.on('update', bundle); // on any dep update, runs the bundler
bundle();
});
Then in the JS code:
var insertCss = require('insert-css');
insertCss(require('../../stylus/pages/dashboard.styl'));
Every option in the Transform options works, except I get no Sourcemaps in the resulting CSS (in the browser).
It appears Stylify only accepts settings passed in with the set object.
browserify_instance.transform('stylify', {
use: [...]
set: {
sourcemap: { inline: global.ENV === 'development' },
compress: global.ENV === 'production'
}
});
Related
I'd like to use the the following vue.config.js with Quasar:
module.exports = {
publicPath:
process.env.NODE_ENV === "production"
? "/static/dist/"
: "http://127.0.0.1:8080",
outputDir: "../../static/dist",
indexPath: "../../../templates/index.html",
pages: {
index: {
entry: "src/main.js",
title: "QuestionTime",
},
},
devServer: {
devMiddleware: {
publicPath: "http://127.0.0.1:8080",
writeToDisk: (filePath) => filePath.endsWith("index.html"),
},
hot: "only",
headers: { "Access-Control-Allow-Origin": "*" },
},
};
I'd like to have the index.html file generated by the writeToDisk module.
I've updated the quasar.conf.js, but the index.html is not generated:
module.exports = configure(function (ctx) {
return {
publicPath:
process.env.NODE_ENV === "production"
? "/static/dist/"
: "http://127.0.0.1:8080",
outputDir: "../../../static/dist",
indexPath: "../../../templates/index.html",
pages: {
index: {
entry: "src/main.js",
title: "QuestionTime",
},
},
// https://v2.quasar.dev/quasar-cli-webpack/supporting-ts
supportTS: false,
// https://v2.quasar.dev/quasar-cli-webpack/prefetch-feature
// preFetch: true,
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://v2.quasar.dev/quasar-cli-webpack/boot-files
boot: [
'axios',
],
// https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-css
css: [
'app.scss'
],
// https://github.com/quasarframework/quasar/tree/dev/extras
extras: [
// 'ionicons-v4',
// 'mdi-v5',
// 'fontawesome-v6',
// 'eva-icons',
// 'themify',
// 'line-awesome',
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
'roboto-font', // optional, you are not bound to it
'material-icons', // optional, you are not bound to it
],
// Full list of options: https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js#Property%3A-build
build: {
vueRouterMode: 'hash', // available values: 'hash', 'history'
// transpile: false,
// publicPath: '/',
// Add dependencies for transpiling with Babel (Array of string/regex)
// (from node_modules, which are by default not transpiled).
// Applies only if "transpile" is set to true.
// transpileDependencies: [],
// rtl: true, // https://quasar.dev/options/rtl-support
// preloadChunks: true,
// showProgress: false,
// gzip: true,
// analyze: true,
// Options below are automatically set depending on the env, set them if you want to override
// extractCSS: false,
// https://v2.quasar.dev/quasar-cli-webpack/handling-webpack
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack (chain) {
chain.plugin('eslint-webpack-plugin')
.use(ESLintPlugin, [{ extensions: [ 'js', 'vue' ] }])
}
},
...
Pkg quasar... v2.9.2
Pkg #quasar/app-webpack... v3.6.1
Pkg webpack... v5
I' running Quasar with webpack. I there anything I missed / to take care of?
I've added .scss styling to my site. The .scss files sit next to their .jsx components.
I reference the styles in .jsx like this:
import styles from './guest-card.component.scss'
...
<Card className={styles.card}>
Everything looks great when I run my local server webpack-dev-server --inline --progress --config build/webpack.cold.conf.js
When I build for distributing the app, such as Development machine or QA machine I run npm run build. This builds a dist folder with everything compiled.
When I view my site on a dev/qa server my styles are missing.
Looking in the dist folder I see a /static/css/app.css with my compiled styles. Great! The styles look correct.
My question: What do I do to include these /static/css/app.css in my production site? I tried adding a <link rel="stylesheet" ... to include it and im sure that would work but would give a 404 on my local machine.
Whats the correct way of having styles built
So my question is:
My question is - how do I get my app to reference this new app.css? If I add a
build.js
'use strict';
require('./check-versions')();
process.env.NODE_ENV = 'production';
const ora = require('ora');
const rm = require('rimraf');
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../config');
const webpackConfig = require('./webpack.prod.conf');
const spinner = ora('building...');
spinner.start();
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err;
webpack(webpackConfig, function (err, stats) {
spinner.stop();
if (err) throw err;
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n');
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'));
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'));
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
});
webpack.prod.conf.js
const paths = require('./paths');
const utils = require('./utils');
const webpack = require('webpack');
const config = require('../config');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env');
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].js'),
chunkFilename: utils.assetsPath('js/[id].js')
},
resolve: {
alias: {
settings: `${paths.settings}/dist.js`
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': env
}),
// UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].css'),
// set the following option to `true` if you want to extract CSS from
// codesplit chunks into this main css file as well.
// This will result in *all* of your app's CSS being loaded upfront.
allChunks: false,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
host: '#_host_#',
template: 'index.html',
inject: false,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vender modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks(module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(paths.nodeModules) === 0
);
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: paths.static,
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
]),
// copy any extra assets to root dist
new CopyWebpackPlugin([
{
from: `${paths.root}\\web.config`,
to: config.build.dist,
ignore: ['.*']
}
])
]
});
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin');
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
`\\.(${
config.build.productionGzipExtensions.join('|')
})$`
),
threshold: 10240,
minRatio: 0.8
})
);
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}
module.exports = webpackConfig;
webpack.base.conf.js
const paths = require('./paths');
const utils = require('./utils');
const config = require('../config');
module.exports = {
context: paths.root,
entry: {
app: './src/main.jsx'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
'#': paths.src,
api: paths.api,
settings: `${paths.settings}/local.js`
}
},
externals: {
bamboraCheckout: 'customcheckout'
},
module: {
rules: [
...(config.dev.useEslint ? [{
test: /\.js$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [paths.src, paths.test],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
}] : []),
{
test: /\.(js|jsx|mjs)$/,
loader: 'babel-loader',
include: [paths.src, paths.test]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
};
webpack.cold.conf.js
const paths = require('./paths');
const merge = require('webpack-merge');
const devWebpackConfig = require('./webpack.hot.conf.js');
module.exports = new Promise(resolve => {
devWebpackConfig.then(base => {
let webpackConfig = merge(base, {
resolve: {
alias: {
api: `${paths.api}/fakes`
}
}
});
resolve(webpackConfig);
})
});
If you miss link to your generated style file in index.html then you should search for problem here, because this plugin is responsible for it
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
host: '#_host_#',
template: 'index.html',
inject: false,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
I just looked through plugin documentation, probably you need to remove inject: false. Default is true, and is putting your assets into index.html
Here is my problem.
All mentioned paths as per below gruntfile.js are watched fine (shown in grunt --verbose -v). Livereload fires whenever I change files (at least --verbose shows livereload fires). But the page is live reloaded ONLY in case I change my /development/index.html (in Sublime Text) or /less/mainpage.less (with contrib-less).
If I change development/img//* or anyting in /test//*, livereload FIRES but do not RELOAD my page.
I would really appreciate if someone could help.
Here is my folder structure:
source location root: /development/
destination location root: /test/
Here is my gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
watch: {
livereload: {
files: ['development/*.html', "test/**/*", "development/img/**/*"],
options: {
livereload: true,
spawn: false
}
},
// watch tasks start here
scripts: {
files: ['development/js/**/*.js'],
tasks: ['concat']
},
html: {
files: ['development/*.html'],
tasks: ['copy:html']
},
less_compile: {
files: ['development/a_source/less/**/*.less'],
tasks: ['less', "stripCssComments"]
},
images: {
files: ['development/img/**/*'],
tasks: ['tinyimg']
}
},
// runs local server for livereload
connect: {
sever: {
options: {
hostname: 'localhost',
port: 3000,
base: 'test/',
livereload: true
}
}
},
// *** *.html, *.img copy task here
copy: {
html: {
expand: true,
cwd: 'development',
src: '*.html',
dest: 'test/',
}
},
// *** LESS tasks here
less: {
compile: {
options: {
paths: ["development/b_components/less/"]
},
files: {
"temp/css/style.css": "development/a_source/less/style.less"
}
}
}, // compiles less and put compiled version into /temp/css/style.test
stripCssComments: {
dist: {
files: {
'test/css/style.css': 'temp/css/style.css'
}
}
}, // strips comments from /temp/css/style.css and copies it to /test/
// minify images
tinyimg: {
dynamic: {
files: [{
expand: true, // Enable dynamic expansion
cwd: 'development/img/', // Src matches are relative to this path
src: ['**/*.{png,jpg,gif}'], // Actual patterns to match
dest: 'test/img/' // Destination path prefix
}]
}
}
}); //initConfig
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-strip-css-comments');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-tinyimg');
grunt.registerTask('default', ["connect", "watch"]);
}; //wrapper function
Try this
livereload:{
options:{
livereload:'<%= connect.options.livereload %>'
},
files:[
'app/{,*/}*.html',
'app/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
This should reload if you make changes in your images folder. (Customize the URL according to your structure.)
OK. I just wanted to wrap up after I solved all my problems.
I arrived at the following acceptably working setup:
- as per above: Grunt serves as only "files" worker doing all compile / concat / copy etc.
work.
- browser-sync is my local server (with bunch of other vital capabilities) and fast livereload tool, that additionally syncs
several open test windows (https://browsersync.io/).
- Divvy: great addition to my workflow capable of arranging windows on the desktop on the fly (http://mizage.com/divvy/).
Update:
Soon after I switched to Gulp + Browsersync. I could not be satisfied more. Gulp works roughly 10 times faster and Browsersync is smooth and convenient.
Here is my gulpfile.js example just to demonstrate the tasks this pair manages for me:
var gulp = require("gulp"),
gutil = require("gulp-util"),
less = require('gulp-less'),
concat = require('gulp-concat'),
browserify = require('gulp-browserify'),
browserSync = require('browser-sync').create(),
gulpcopy = require('gulp-copy'),
newer = require('gulp-newer'),
imagemin = require('gulp-imagemin'),
autoprefixer = require('gulp-autoprefixer'),
uglifyjs = require('gulp-uglify'),
cleanCSS = require('gulp-clean-css'),
uglifycss = require('gulp-uglifycss'),
htmlmin = require('gulp-htmlmin'),
htmlhint = require("gulp-htmlhint"),
htmlv = require('gulp-html-validator'),
validatecss = require('gulp-w3c-css'),
sourcemaps = require('gulp-sourcemaps');
var lessMain = ["src/styles/less/styles.less"],
lessSources = ["src/styles/less/*.less", "src/styles/**/*.css"],
jsSources = "src/js/*.js",
jsonSources = ["src/js/*.json"],
htmlSources = ["src/html/*.html"],
imgSources = ["z_design/images/processed/**/*.*"],
imgDest = ["public/img/**/*.*"],
cssTemp = ["src/temp/css/styles.css"],
srcjQuery = "node_modules/jquery/dist/jquery.min.js",
srcMustache = "node_modules/mustache/mustache.min.js";
gulp.task("message", function() {
gutil.log("============= Gulp script started ==============");
});
// compiling less
gulp.task("less-compile", function() {
gulp.src(lessMain)
// switches sourcemaps on/off
.pipe(sourcemaps.init())
.pipe(less()
.on("error", gutil.log))
// switches sourcemaps on/off
.pipe(sourcemaps.write())
// change .dest("folder") to "public/css"
// to make no-autoprefix
// or to "src/temp/css/" to switch autoprefix on
.pipe(gulp.dest("public/css"))
});
// prepare & copy js files
gulp.task("js", function() {
gulp.src([srcjQuery, srcMustache, jsSources])
.pipe(concat("script.js"))
.pipe(gulp.dest("public/js/"))
});
// .pipe(browserify())
// {bundleExternal: false}
// copy JSON files
gulp.task("copyjson", function() {
gulp.src(jsonSources)
.pipe(newer("public/js/"))
.pipe(gulpcopy("public/js/", {
prefix: 2
}))
});
// copy html files
gulp.task("copyhtml", function() {
gulp.src(htmlSources)
.pipe(newer("public/"))
.pipe(gulpcopy("public/", {
prefix: 2
}))
});
// --- minify & compress images: 2 tasks - auto and manual
// minify & copy images - manual task
gulp.task("img-ondemand", function() {
gulp.src("z_design/images/unprocessed/**/*.*")
.pipe(newer("public/img/"))
.pipe(imagemin({
progressive: true
}))
.pipe(gulp.dest('z_design/images/processed/'))
});
// minify & copy images - automatic task
gulp.task("processimages", function() {
gulp.src(imgSources)
.pipe(newer("public/img/"))
.pipe(imagemin({
progressive: true
}))
.pipe(gulp.dest('public/img/'))
});
// --- end
// forced reload
gulp.task("reload", function() {
browserSync.reload();
});
// autoprefixer
gulp.task("autoprefix", function() {
gulp.src(cssTemp)
.pipe(autoprefixer({
browsers: ['last 3 versions', 'safari 5', 'ie 8', 'ie 9', 'ie 10', "ie11", 'opera 12.1', 'ios 6', 'android 4'],
cascade: false
}))
.pipe(gulp.dest("public/css/"))
});
// watching for changes
gulp.task("watch", function() {
gulp.watch(lessSources, ["less-compile"])
gulp.watch(jsSources, ["js"])
gulp.watch(jsonSources, ["copyjson"])
gulp.watch(htmlSources, ["copyhtml"])
gulp.watch(imgSources, ["processimages"])
gulp.watch(imgDest, ["reload"])
gulp.watch("src/temp/css/styles.css", ["autoprefix"])
});
// serving localhost
gulp.task('browser-sync', function() {
browserSync.init({
server: ["public", "src"],
watchTask: true,
open: false,
files: ["public/*.html", "public/css/*.css", "public/js/*.*",
"public/img/**/*.*"]
});
});
// === production preparations: RUN SEPARATE TASKS ON DEMAND ===
// --- minify & compress HTML, CSS, JS
// uglify JS
gulp.task("compress-js", function() {
gulp.src("public/js/script.js")
.pipe(uglifyjs())
.pipe(gulp.dest('public/js/'))
});
// uglify CSS
gulp.task('uglify-css', function() {
gulp.src('public/css/styles.css')
.pipe(uglifycss({
"debug": true,
"uglyComments": true
}))
.pipe(gulp.dest('public/css/'));
});
// compress HTML
gulp.task('compress-html', function() {
return gulp.src('src/html/*.html')
.pipe(htmlmin({
collapseWhitespace: true,
removeComments: true
}))
.pipe(gulp.dest('public/'));
});
// --- lint HTML and validate CSS
// lint html
gulp.task('lint-html', function() {
gulp.src("public/*.html")
.pipe(htmlhint())
.pipe(htmlhint.reporter())
});
// validate html
// Option format set to html
gulp.task('validate-html', function() {
gulp.src('public/*.html')
.pipe(htmlv({
format: 'html'
}))
.pipe(gulp.dest('src/temp/validation/'));
});
// add css validation
gulp.task('validate-css', function() {
gulp.src('public/css/*.css')
.pipe(validatecss())
.pipe(gulp.dest('src/temp/validation/'));
});
gulp.task("validate", ["validate-html", "validate-css", "lint-html"]);
gulp.task("compress", ["compress-js", "uglify-css", "compress-html"]);
gulp.task("default", ["watch", "browser-sync"]);
// =======================
I have been trying to get a working wallaby.js configuration file for my meteor project and simply can't get it to work. I've borrowed from https://github.com/xolvio/automated-testing-best-practices and I have this currently:
const babel = require('babel-core')
const path = require('path')
const wallabyWebpack = require('wallaby-webpack')
module.exports = function (wallaby) {
const webpackConfig = {
resolve: {
root: path.join(wallaby.projectCacheDir, 'imports'),
extensions: ['', '.js', '.jsx', '.json']
},
module: {
loaders: [
// JavaScript is handled by the Wallaby Babel compiler
{ test: /\.json$/, loader: 'json-loader' }
]
}
}
const wallabyPostprocessor = wallabyWebpack(webpackConfig)
const appManifest = require(path.resolve('../.meteor/local/build/programs/web.browser/program.json')).manifest;
const meteorPackageFiles = appManifest
.filter(function (file) {
return file.type === 'js' && file.path.startsWith('packages/')
})
.map(function (file) {
/* var basePath = packageStubs.indexOf(file.path) !== -1 ?
'tests/client/stubs' :
'src/.meteor/local/build/programs/web.browser';
*/
var basePath = '../.meteor/local/build/programs/web.browser'
return { pattern: path.join(basePath, file.path) }
})
return {
files: [
{ pattern: '**/*.test.*', ignore: true },
'startup/**/*.jsx',
'startup/**/*.js'
].concat(meteorPackageFiles),
tests: [
'**/*.test.*'
],
compilers: {
'**/*.js*': wallaby.compilers.babel({
babel,
presets: ['react', 'es2015', 'stage-2']
})
},
env: {
type: 'node'
},
testFramework: 'mocha'
}
}
This code successfully loads the startup files for the client-side, and the tests, but this simple test:
import should from 'should'
import buildRegExp from './buildregexp.js'
describe('buildRegExp', function() {
it('splits on word characters', function() {
buildRegExp('test this-thing:out').should.equal('(?=.*test)(?=.*this)(?=.*thing)(?=.*out).+')
})
})
fails on line 1, because the npm module "should" is not found.
Does anyone have a working wallaby config or should I just give up?
meteor test --driver-package=practicalmeteor:mocha works, so the error is in the wallaby config.
I've set up a gruntfile that looks like the following. The aim being to perform e2e tests using protractor for my angularjs project. When running this using mochaProtractor Chrome fires up as expect but the lint is telling me that I'm missing the dependancies for the expect statement. This should referencing the assertion library chai. How do I include dependencies for chai to get this to work correctly?
Thanks
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
watch: {
scripts: {
files: ['public/specs/e2e/*.js'],
tasks: ['mochaProtractor','jshint'],
options: {
spawn: false,
},
},
},
jshint: {
all: [
'Gruntfile.js',
'public/app/js/*.js'
],
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
unused: true,
boss: true,
eqnull: true,
node: true
}
},
mochaProtractor: {
options: {
browsers: ['Chrome']
},
files: ['public/specs/e2e/*.js'],
baseUrl: 'http://localhost:3000/'
},
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-mocha-protractor');
Below is the spec I'm trying to test against. Note: I added the require statement at the top in attempt to get it to work. Any thoughts?
var chai = require('chai');
var expect = chai.expect;
describe("Given a task entry screen", function() {
ptor = protractor.getInstance();
beforeEach(function() {
ptor.get('#/');
button = ptor.findElement(protractor.By.className('btn-say-hello'));
button.click();
});
it('says hello', function() {
message = ptor.findElement(protractor.By.className('message'));
expect(message.getText()).toEqual('Hello!');
});
});
You have to add chai as a dev dependency in your package.json.
{
"name": "yourProject",
"devDependencies": {
"chai": "~1.8.1"
}
}
then install the dependenvy via
npm install`
and then you should be able to write a spec :
var chai = require('chai');
var expect = chai.expect;
describe("Given a task entry screen", function() {
ptor = protractor.getInstance();
beforeEach(function() {
ptor.get('#/');
button = ptor.findElement(protractor.By.className('btn-say-hello'));
button.click();
});
it('says hello', function() {
message = ptor.findElement(protractor.By.className('message'));
expect(message.getText()).toEqual('Hello!');
});
});