Gulp 4 watch task is not detecting changes - javascript

I am trying to switch to Gulp version 4 from Gulp version 3 and I am constantly having issues with watch task, it will not detect changes when the tracked SCSS file is changed. I made a simple example of the watch function since it is easier for debugging.
Ubuntu 17.10
Node v8.9.4
Npm 6.9.0
Gulp CLI version: 2.2.0
Gulp Local version: 4.0.2
I tried removing gulp and gulp-cli completely and installing it again, removing node_modules folder and creating package.json file from scratch but the result is the same. "Starting 'watch'..." and nothing else.
package.json
{
"name": "starter",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"gulp": "^4.0.2",
"gulp-sass": "^4.0.2"
}
}
gulpfile.js
const {src, dest, watch} = require('gulp');
const sass= require('gulp-sass');
function style() {
return src('./scss/**/*.scss')
.pipe(sass())
.pipe(dest('./css'));
}
function watchTask() {
watch('./scss/**/*.scss', style);
}
exports.style = style;
exports.watch = watchTask;
Note: Style task is working correctly and moving all .scss files from source to destination.
I really appreciate any help since I am running out of ideas.

gulp watch detects changes after it boots up, not between this run and last run of gulp watch.
You need to tell gulp watch to run the first style task regardless.
function watchTask() {
watch('./scss/**/*.scss', {ignoreInitial: false}, style);
}
Then it will re-run style task whenever you touched some scss file again.
Update:
Are you using files on docker or a network mapped disk? You might need to turn on {usePolling: true} as documented "needed for successfully watching files over a network or other non-standard situations. "

Related

Prevent nodemon from restarting due to changes to a json-file

I have a nodemon server running, but if I change a file with fs.writeFileSync nodemon restarts and the json-file loses its data.
I tried to prevent this by putting a ignore in the package.json
"nodemonConfig": {
"ignore": ["*.json"]
}
This is not working. I think it could be because I installed nodemon global. Then I found another possibility to prevent this by creating a nodemon.json with:
{
"ignore": ["*.json"]
}
but this is also not working. The third possibility was to write:
nodemon --ignore '[users.json]'
in the terminal. It could be that I wrote the line wrong or something else, but I am just not getting the solution for this problem.
You can add nodemon configuration within the package.json file, for example:
{
"name": "label",
"version": "0.0.1",
"nodemonConfig": {
"ignore": ["*.json", "public/javascripts/*.js"]
},
"author": "#aqui",
"license": "GPL-3.0"
}
The key must be nodemonConfig. Ignore rules can be specified as an array of globs or complete filenames
Or you can edit your package.json file to update the run scripts this way.
"scripts": {
"dev": "nodemon server.js --ignore *.json"
},

How can I export a React Component as an NPM package to use in separate projects?

I have created a React component inside a project that I'd like to use in multiple projects. At the moment, I only care about doing this locally and for development. The React Component is rendered into the root div, the project uses webpack and babel to transpile JSX, ES6 and some ES7 features into a bundle.
I thought it would be simple to export this component such that I can simply run npm install MyComponent and begin using it in a fresh project. However, I find it isn't so straight forward. In particular, I've been reading for hours and hours and only seem to be getting more confused.
If my end goal is to keep developing 'MyComponent' in its containing project, while using 'MyComponent' in any number of other local projects, what are my options? The first thing I did was change the main key of my package.json to /src/components/MyComponent and run npm pack. This produces a tgz file I can install via its absolute filepath in other projects. However, I found that the es6 and jsx was not being transpiled and so my client projects would be unable to parse MyComponent. I then used webpack to transpile into lib/MyComponent, but when I have import MyComponent from './path/to/MyComponent-1.0.0.tgz I'd only see {} (an empty object) in the console.
Searching for solutions to my problem turn up many different approaches pulling together NPM, Grunt, Gulp, Babel, Webpack, etc.. And I am worried it will be many many more hours (days?) before I can grind that down to something understandable.
Given my requirements, what is the simplest solution I can implement to 1) compile down my React Component to the simplest to import module 2) import it into any local projects 3) continue to develop the package in the original host project and have changes easily propagate to client projects.
In general, if you're going to begin creating React components as separated packages (which is a great pattern, for all the reasons you've already mentioned) - you're going to need to get at least a bit familiar with webpack and babel. There's a ton to learn here, but let me try to point you in the right direction:
// webpack.config.js
/* eslint-disable */
const path = require('path')
const webpack = require('webpack')
const ENVIRONMENT = process.env.NODE_ENV
const PRODUCTION = ENVIRONMENT === 'production'
const SOURCEMAP = !PRODUCTION || process.env.SOURCEMAP
const library = 'your-lib-name' // << RENAME THIS <<
const filename = PRODUCTION ? `${library}.min.js` : `${library}.js`
const plugins = []
if (PRODUCTION) {
plugins.push(
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(ENVIRONMENT),
}),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
output: { comments: false, semicolons: false },
sourceMap: SOURCEMAP,
})
)
}
module.exports = {
devtool: SOURCEMAP ? 'source-map' : 'none',
entry: `${__dirname}/path/to/your/component.js`, // << RENAME THIS <<
externals: {
'react': 'react',
'react-dom': 'react-dom',
},
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
}],
},
output: {
filename,
library,
path: `${__dirname}/lib`,
libraryTarget: 'umd',
umdNamedDefine: true,
},
plugins,
}
I know that looks like a bunch - but it handles the majority of what you're going to want. In specific:
If you specify NODE_ENV=production when building, this will uglify/minify your package, and do some other trimming which you may want later.
Building with this script will output a sourcemap, which you can use with dev tools to inspect your minified code in the debugger window, among other things.
This marks react and react-dom as externals - which means they won't get bundled up and packaged inside your bundle. This is great - because it means you won't get 2+ copies of react's filesize just because you've imported your own component!
To use it, though, you now need some package.json love.
package.json
{
"name": "Your Name",
"version": "0.0.1",
"description": "This is my awesome react package!",
"main": "path/to/your/component.js",
"author": "Your Name",
"license": "MIT",
"repository": { /* Your Repo Info Here */ },
"dependencies": {
"any-packages-you-need-included-in-builds": "^1.0.0"
},
"devDependencies": {
"babel-cli": "^6.22.2",
"babel-loader": "^7.1.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.22.0",
"prop-types": "^15.5.10",
"react-dom": "^15.6.1",
"webpack": "^3.0.0"
},
"scripts": {
"build": "yarn prebuild && NODE_ENV=production webpack",
"prebuild": "mkdir -p ./lib && rm -rf ./lib/*"
}
}
Obviously, you can have a lot more here if you need it - such as other babel-plugin-* plugins that you use in your transpilation, other packages, etc.But this set will let your webpack build run. Note that the scripts here assume you're using yarn - so that you can run yarn build, and that you're on a posix system, for mkdir to work. If you're on windows or not using yarn, just update the scripts accordingly.
The rest is just learning to publish your package to npm or another package repository. Primarily, that's just setting the version number in package.json to something new (npm version) and then publishing (npm publish). You will have to have an npm account for this, of course - and be logged in (npm login).
Once you've published to npm you can just yarn add your-package-name.
Remember, though - we marked react and react-dom as external - so in the consuming package, you'll need to make sure they're available as window.React and window.ReactDOM - or you'll need to include the component directly from node_modules/your-package-name/path/to/your/component.js
You don't need to npm pack a package to use it. If you make your component into a git repo and put it on Github, you can use NPM to install it directly from Github by using npm install alex/mycomponent where alex is your github username and mycomponent is the repo name. Re-running that command will re-install from Github, in case you make changes to the repo.
Once you're happy with the component, you can upload it to the NPM registry to install like any other package (npm install name). Using Github at first makes it a bit easier to develop.
Webpack might not compile things from node_modules by default. Usually, packages are pre-compiled before being published anyway, but you should be able to configure webpack to build your 'packaged' component, along with the rest of your app. Maybe this will help: https://stackoverflow.com/a/38008149/7486612
In order to push react libraries into NPM, you may need some boilerplate which will install and convert many things for you (and you can still use your current react module as the main source, just follow the guides at the end of my answer, then you will surely get all the ideas)
Or you can also refer to my previous answer to a similar question:
Issue with publishing to npm
=====
I've also pushed several react libraries successfully into NPM:
https://www.npmjs.com/~thinhvo0108
=====
Your github repositories' folder structure should also look like mine:
https://github.com/thinhvo0108/react-paypal-express-checkout
=====
Useful tutorial below here:
(boilerplate source) https://github.com/juliancwirko/react-npm-boilerplate
(author's article) http://julian.io/creating-react-npm-packages-with-es2015/
Start by looking at existing component library, eg Material UI.
Specifically check out npm scripts they have (see package.json):
"build:es2015": "cross-env NODE_ENV=production babel ./src --ignore *.spec.js --out-dir ./build",
"build:es2015modules": "cross-env NODE_ENV=production BABEL_ENV=modules babel ./src/index.js --out-file ./build/index.es.js",
"build:copy-files": "babel-node ./scripts/copy-files.js",
"build:umd:dev": "webpack --config scripts/umd.webpack.config.js",
"build:umd:prod": "cross-env NODE_ENV=production webpack --config scripts/umd.webpack.config.js",
"build": "npm run build:es2015 && npm run build:es2015modules && npm run build:copy-files && npm run build:umd:dev && npm run build:umd:prod",
That's example of very involved and high quality component library, that makes sure that regardless of your build pipeline you'll be able to use it.
Setting up build process with webpack might be cumbersome, but don't concentrate on that too much from the begining, and cover cases that are most straight forward to you.
Also check out https://storybook.js.org/ while working on your components.

grunt not running Qunit tests correctly

Situation : I am currently using QUnit to test a project in TypeScript/Javascript and everything works fine when I'm running them in a browser.
Problem : I'm trying to use grunt to run the QUnit tests in a headless mode (I need it for continuous integration testing) and the tests don't run properly.
Configuration
Here's how I have things currently set up :
Gruntfile.js
package.json
src/
- Ts source files
test/
- config.js
- Test.ts
- Test.js
- test.html
Gruntfile.js
/*global module:false*/
module.exports = function(grunt) {
grunt.initConfig({
connect: {
server: {
options: {
port: 8000,
base: '.'
}
}
},
qunit: {
all: {
options: {
urls: [
'http://localhost:8000/test/test.html'
]
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.registerTask('test', ['connect', 'qunit']);
};
package.json
{
// Name, version, description, repo and author fields...
"engines": {
"node": ">= 0.10.0"
},
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-watch": "~0.6.1",
"grunt-contrib-connect": "~0.9.0",
"grunt-contrib-qunit": "~0.5.2"
}
}
And then I have a .travis.yml file to run all of this. I don't know if it's really important because the tests don't run either in travis or in my local environment, but here is it anyways :
language: node_js
node_js:
- "0.11"
- "0.10"
before_install:
- "npm install grunt --save-dev"
- "npm install -g grunt-cli"
install:
- "npm install"
- "npm install -g typescript"
script:
- "tsc --module amd --target ES5 ./src/*.ts"
- "grunt test --verbose --force"
And here's the part that errors in the travis build : http://puu.sh/eKpWj/35614680e1.png
(I currently have ~20 assertions that pass when I'm running them in a browser. Also, the typescript compilation runs ok.)
Edit : And as someone asked fot it, here's the content of the Test.html file : http://pastebin.com/LN3igmjc
Edit 2 : Here's also the content of config.js :
var require = {
baseUrl: "../src/"
};
Actually I managed to make it work.
I changed two things :
I wasn't compiling the tests, as tsc --module amd --target ES5 ./src/*.ts compiled the files in the src folder, and the test files were in the test folder. I'm bashing myself for this one...
So I simply added tsc --module amd --target ES5 ./test/*.ts in the .travis.yml file
The biggest problem was that the QUnit tests were trying to start before the work of require.js. The solution I used was to tell QUnit to not start tests automatically by using QUnit.config.autostart = false; and make them start when I want with QUnit.start(); I placed this start() at the end of my Test.js file so that the tests start only when QUnit is done loading.

NPM installing modules to application root

I messed something up and I've done my best to fix it, but no luck.
Whenever I run 'npm install' on a new node project, it installs all of my dependencies to the root of the application instead of in /node_modules/ like you'd expect in a default application.
For example-
My package.json
{
"name": "hello-world",
"description": "hello world test app",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "3.x"
}
}
When I use 'npm install' I end up with this:
I've tried setting my PATH like in this solution:
How to use package installed locally in node_modules?
but that didn't seem to do much. Help?
observe that you have the cache variable set in that directory
strict-ssl = false
userconfig = /private/tmp/timothy/timothy_local_job_1367532952281_60137/.npmcfg
cache = /Users/tomhorton/Documents/Repository/helpmestackoverflow
root = ./node_modules
That timothy stuff is from a module that I installed shortly before everything went haywire-
I removed that stuff and the defaults took over. Everything works great!

Using Travis-CI for client-side JavaScript libraries?

I'm not sure to use Travis-CI for my client-side JavaScript library or not, because it compiles with NodeJs on Travis-CI servers.
I want to know is this a good approach to use some kind of continuous integration such as Travis-CI for client-side libraries or not?
Yes of course you should use continous integration with client side libraries.
I personally use PhantomJS (headless webkit browser) which is already installed in Travis-CI. I think this is the better option for client-side stuff than NodeJs.
If you use Grunt, it gets even easier to use, all you need is a simple Gruntfile.js file, your tests that run in browser (I use QUnit), and a simple .travis.yml
Gruntfile.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
qunit: {
files: ['test/index.html']
}
});
// Load plugin
grunt.loadNpmTasks('grunt-contrib-qunit');
// Task to run tests
grunt.registerTask('test', 'qunit');
};
.travis.yml:
before_script:
- sudo npm install -g grunt
script: grunt test --verbose --force
You can see it in action at one of my projects (source on GitHub).
I started with the answer from Odi and moved to gulp to get it working. If you specify node_js as your language in your travis file, travis will automatically run
npm install
followed by
npm test
The first will install any devDependencies specified in a package.json file, the second will run the script named "test" also from package.json. Below you'll find the three files I needed to have in the top level of my repo for travis to run a single qunit suite.
.travis.yml
language: node_js
node_js:
- "0.10"
gulpfile.js
var gulp = require('gulp'),
qunit = require('gulp-qunit');
gulp.task('default', function() {
return gulp.src('./tests/unit/unittests_nupic-js.html')
.pipe(qunit());
});
package.json
{
"name": "nupic-js",
"version": "0.0.1",
"description": "JavaScript port of NuPIC",
"license": "GPL-3.0",
"repository": "iandanforth/nupic-js",
"bugs": { "url" : "http://github.com/iandanforth/nupic-js/issues"
},
"author": {
"name": "Ian Danforth",
"email": "iandanforth#gmail.com"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"test": "gulp"
},
"keywords": [
"numenta",
"nupic",
"machine learning"
],
"devDependencies": {
"gulp-qunit": "~0.2.1",
"gulp-util": "~2.2.14",
"gulp": "~3.5.1"
}
}
Odi's answer updated and using npm to resolve dependencies:
.travis.yml
language: node_js
node_js:
- "6"
.Gruntfile.js
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
qunit: {
files: ['./test/qunit.html']
}
});
// Load plugin
grunt.loadNpmTasks('grunt-contrib-qunit');
// Task to run tests
grunt.registerTask('test', 'qunit');
};
Package.json (relevant parts)
"devDependencies": {
"grunt": "^1.0.1",
"grunt-contrib-qunit": "^1.3.0"
},
"scripts": {
"test": "grunt test"
}
You can try the configuration locally by running npm install and then npm test.
I found this example. Quite comprehensive!
https://github.com/jonkemp/gulp-qunit
run:
npm install
gulp test
It also has tasks for lint watching files, coverage reports and more.

Categories