I am new to gulp and I just create a gulpfile.js. I am trying to run gulp run but I am getting -bash: gulp: command not found
Not sure as to why this is happening as I have it installed locally.
package.json:
{
"name": "taglr",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "webpack --config webpack.config.js && node ./build/index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel": "^6.5.2",
"babel-core": "^6.7.2",
"babel-loader": "^6.2.4",
"deepmerge": "^0.2.10",
"glue": "^3.2.0",
"hapi": "^13.2.1",
"jquery": "^2.2.1",
"react": "^0.14.7",
"react-dom": "^0.14.7",
"react-router": "^2.0.1"
},
"devDependencies": {
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"extract-text-webpack-plugin": "^1.0.1",
"gulp": "^3.9.1",
"nodemon": "^1.9.1",
"webpack": "^1.12.14",
"webpack-dev-server": "^1.14.1"
}
}
gulpfile.js:
var gulp = require('gulp');
var webpack = require('webpack');
var path = require('path');
var fs = require('fs');
var DeepMerge = require('deep-merge');
var nodemon = require('nodemon');
// for excluding the building of node_modules in the backend
var nodeModules = {};
fs.readdirSync('node_modules').filter(function(x) {
return ['.bin'].indexOf(x) === -1;
}).forEach(function(mod) {
nodeModules[mod] = 'commonjs ' + mod;
});
// generic config
var defaultConfig = {
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: [
'react',
'es2015'
]
}
}
]
}
};
// if not production build
if (process.env.NODE_ENV !== 'production') {
defaultConfig.devtool = '#eval-source-map';
defaultConfig.debug = true
}
// build config using overrides
function buildConfig(config) {
return DeepMerge(defaultConfig, config || {});
}
var backendConfig = buildConfig({
entry: path.resolve(__dirname, "server/server.js"),
// tells webpack not to touch any built-in modules
target: "node",
externals: nodeModules,
output: {
path: path.resolve(__dirname, "build"),
filename: 'index.js'
},
pluguns: [
]
});
var host = "localhost";
var port = 3000;
var frontendConfig = buildConfig({
entry: path.resolve(__dirname, "app/index.js"),
output: {
path: path.resolve(__dirname, "public/bundle"),
filename: "main.js"
// publicPath: 'http://' + host + ':' + port + 'pubic/bundle'
},
plugins: [
]
});
function onBuild(done) {
return function(err, stats) {
if (err) {
console.log("ERROR: " + err);
} else {
console.log(stats.toString());
}
if (done) {
done();
}
}
}
// build frontend
gulp.task('build-frontend', function(done) {
webpack(frontendConfig).run(onBuild(done));
});
// watch frontend
gullp.task('watch-frontend', function(done) {
webpack(frontendConfig).watch(100, onBuild());
});
// build backend
gulp.task('build-backend', function(done) {
webpack(backendConfig).run(onBuild(done));
});
// watch backend
gullp.task('watch-backend', function(done) {
webpack(backendConfig).watch(100, function(err, stats) {
onBuild()(err, stats);
nodemon.restart();
});
});
gulp.task('build', ['build-frontend', 'build-backend']);
gulp.task('watch', ['watch-frontend', 'watch-backend']);
gulp.task('run', ['watch-frontend', 'watch-backend'], function() {
nodemon({
execMap: {
js: 'node'
},
script: 'build/index.js',
ext: 'js html'
})
});
The problem is that executable gulp isn't found in any directories of your $PATH. If you install it globally, it will be copied in /usr/lib/node_modules or some other directory in your $PATH (depending on your distro), so just use:
npm install -g gulp-cli
Or if you can't use sudo on that machine, you can install it to your project package.json:
npm install --save-dev gulp-cli
Link it:
ln -s node_modules/.bin/gulp gulp
Execute it by using the local symlink:
./gulp run
Related
I am new to nodejs, webpacks and javascripts, looking for assistance.
I have the below project structure using webpack with nodejs:
-dist
-node_modules
-public
--test.png
-routes
--web
---usage.html
--api
---testapi.js
-src
--app.js
-index.html
-package-lock.json
-package.json
-webpack.config.js
webpack.config.js has this structure:
webpack.config.js:
module.exports = {
mode: 'development',
target: "node",
entry: {
main: './src/app.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
extensions: [".js", ".jsx", ".json", ".css"]
},
module: {
rules: [
{
test: /\.(js|jsx)?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.html$/i,
loader: "html-loader",
},
//other rules
]
},
devServer: {
client: {
overlay: true
},
hot: true,
watchFiles: ['src/*', 'index.html'],
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
}
},
plugins: [
new CopyWebpackPlugin({
patterns: ['index.html']
}),
new HtmlWebpackPlugin({
filename: 'usage.html',
template: 'routes/web/usage.html',
}),
//other plugins
]
};
In testapi.js I have a api call using axios :
testapi.js:
const axios = require('axios');
var temp;
const config = {
//some_config
};
axios.get(some_url, config)
.then(async result => {
temp = result.data;
console.log("Results: " + JSON.stringify(temp))
})
.catch(error => {
console.log(error)
});
In usage.html I am calling the testapi.js script (also to cors issue as testapi.js is from a external api) and doing some actions as follows:
usage.html :
//other scripts
<script>
$(document).ready(function () {
$.getScript("testapi.js", async function (result) {
//some logic goes here
});
</script>
//body follows
package.json :
{
"name": //some_app_name,
"version": "1.0.0",
"description": //some_desc,
"dependencies": {
"#babel/core": "^7.18.13",
"async": "^3.2.4",
"aws-amplify": "latest",
"axios": "^0.27.2",
"express": "^4.18.1",
"html-webpack-plugin": "^5.5.0",
"node-fetch": "^2.6.7"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^8.2.5",
"babel-preset-env": "^1.7.0",
"babel-preset-es2016": "^6.24.1",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^6.4.1",
"extract-loader": "^5.1.0",
"file-loader": "^6.2.0",
"html-loader": "^4.1.0",
"html-webpack-partials-plugin": "^0.8.0",
"url-loader": "^4.1.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0"
},
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack",
"prestart": "npm run build",
"start": "webpack && webpack-dev-server --mode development"
}
}
I have tried the below things and nothing seems to be working:
Adding the js file as entry // The api gets called in console but with cors issue and not sure how i can use it in usage.html.
Added plugin in webpack config with :
new CopyWebpackPlugin({
patterns: ['routes/api/testapi.js']
}),
When I do this, I can see the raw code instead of the api response output in Network tab when I load that usage.html page.
Used $get instead of $getScript in usage.html.
Tried moving testapi to src as well and making necessary changes.
Kindly assist me with this
I keep getting error Uncaught ReferenceError: require is not defined in browser even with Webpack and Babel. For some reason I never had to worry about this before. I'm not sure if this error is caused by updated packages or what. I set up a very simple test application for simplicity.
package.json
{
"name": "require-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"engines": {
"node": "16.16.0"
},
"scripts": {
"build": "webpack --config webpack.config.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.18.10",
"#babel/preset-env": "^7.18.10",
"babel-loader": "^8.2.5",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
}
}
webpack.config.js
const path = require('path');
module.exports = {
target: "node",
mode: "production",
output: {
path: path.resolve(__dirname, 'dist'),
clean: true,
filename: (pathData) => {
return 'index.js'
},
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
}
}
src/index.js (js file before build)
const path = require('path');
console.log(path);
dist/index.js (js file after build)
(()=>{var r,e={17:r=>{"use strict";r.exports=require("path")}},t={};r=function r(o){var s=t[o];if(void 0!==s)return s.exports;var p=t[o]={exports:{}};return e[o](p,p.exports,r),p.exports}(17),console.log(r)})();
There're a few things on your code needing changed. First of all, you can't target to build for node while you run that code on browser which is wrong. Secondly, path is designed and built to run on node server specifically, however, there's a fallback for path on browser though which is called path-browserify. You can check its document to see how it works.
Anyway to sum up, you need to switch target as web in the end:
module.exports = {
target: "web",
// ...
}
REVISED
So I am fairly new to this and I am struggling for some time to resolve this, so I would really appreciate help.
Goal: Create dynamic web-page that is using handlebars and D3 for dynamic text and visuals.
What I achieved until now: Use json file stored within to do some data manipulation and render data with hbs and express. Created simple bar chart that uses data from the previous file.
Issue: I am not sure how to completely set up webpack so I can actually see how my page looks like. If I just add script with D3 visuals to hbs I am getting require is not defined, which I get since it's not supported on client side.
folder structure
|main
|data
|data.json
|src
|index.js
|visuals.js
|templates
|views
|index.hbs
|node_modules
|package.json
|package-lock.json
|webpack.config.js
|babel.config.json
My code until now (there might be to many things here because I tried a lot of things plus I was anonymizing as I have sensitive items)
index.js:
const express = require("express");
const fs = require("fs");
const path = require("path");
const hbs = require("hbs");
const Data = JSON.parse(
fs.readFileSync(path.resolve(__dirname, "../data/data.json")).toString()
);
//Some data manipulation
module.exports = clusters; //array to be used in the other file
const app = express();
const publicDirectoryPath = path.join(__dirname, "..");
const viewPath = path.join(__dirname, "../templates/views");
app.set("view engine", "hbs");
app.set("views", viewPath);
app.use(express.static(publicDirectoryPath));
app.get("", (req, res) => {
res.render("index", {
data1: data1,
data2:data2,
});
});
Beginning of visuals.js
const d3 = require("d3");
var dt = require("./index.js");
const clusters = dt.clusters;
webpack.config.js
const path = require("path");
const HandlebarsPlugin = require("handlebars-webpack-plugin");
module.exports = {
entry: [
path.resolve(__dirname, "./src/visuals.js"),
path.resolve(__dirname, "./src/index.js"),
],
output: {
path: path.resolve(__dirname, "./public"),
filename: "bundle.js",
},
module: {
rules: [
{ test: /\.handlebars$/, loader: "handlebars-loader" },
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
],
},
resolve: {//I had errors and warnings with modules, below solved it
modules: [path.resolve(__dirname), "node_modules/"],
extensions: [".js", ".json"],
descriptionFiles: ["package.json"],
},
fallback: {
stream: false,
http: false,
buffer: false,
crypto: false,
zlib: false,
fs: false,
net: "empty",
},
},
plugins: [
new HandlebarsPlugin({//can't say I understood from documentation the setup for hbs
entry: path.resolve(__dirname, "./templates/views/index.hbs"),
output: path.resolve(__dirname, "./public/index.html"),
data: path.resolve(__dirname, "./data/data.json"),
onBeforeSetup: function (Handlebars) {},
onBeforeCompile: function (Handlebars, templateContent) {},
onBeforeRender: function (Handlebars, data, filename) {},
onBeforeSave: function (Handlebars, resultHtml, filename) {},
onDone: function (Handlebars, filename) {},
}),
],
};
package.json
{
"name": "triana_plus",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack --mode development",
"start": "webpack serve --config ./webpack.config.js --open chrome"
},
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.12.10",
"#babel/preset-env": "^7.12.10",
"babel-loader": "^8.2.2",
"handlebars-webpack-plugin": "^2.2.1",
"webpack": "^5.10.1",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0",
"webpack-node-externals": "^2.5.2"
},
"dependencies": {
"d3": "^6.3.1",
"express": "^4.17.1",
"fs": "0.0.1-security",
"handlebars-loader": "^1.7.1",
"hbs": "^4.1.1",
"net": "^1.0.2",
"path": "^0.12.7",
"request": "^2.88.2"
}
}
babel.config.json
{
"presets": ["#babel/preset-env"]
}
What the error you posted means is that webpack is being asked to create some JS bundles that reference node packages like http. Referencing packages like that in client-side code bundles won't work since it cannot package node modules in the JS artifacts.
Make sure that no node-specific packages are required/imported for files you're bundling through webpack. Since it looks like you're creating an express app, keep the express-specific files outside of the folder visited by webpack.
I'm trying to bundle my node.js project into one single file, which would contain all the modules that it needs, by using webpack.
After creating a bundle.js file, I cannot run it because some functions from required modules are not recognized:
In the Server.js file I had required 'http' , and used http.createServer() function.
When I'm running the file, it says: TypeError: r.createServer is not a function
How can I bundle the project with all of it's modules correctly?
Relevant parts of my Package.json file:
"dependencies": {
"lodash": "4.17.4"
},
"devDependencies": {
"babel-loader": "^7.1.4",
"eslint": "^4.19.1",
"jasmine": "^3.1.0",
"webpack": "^4.5.0",
"webpack-cli": "^2.0.14"
},
"scripts": {
"test": "npm run lint && jasmine",
"lint": "sh util/lintRunner.sh",
"fix": "sh util/lintFixer.sh",
"build": "webpack -p",
"clean": "rm -rf dist/"
}
My webpack.comfig.js file:
const path = require('path');
module.exports = {
entry: [
'./Server/Server.js',
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
],
},
node: {
fs: 'empty',
dns: 'empty'
}
};
You need to tell WebPack where your bundled javascript is going to run; in this case in a nodejs environment.
Try adding target: 'node' to your configuration.
Read more about the target attribute: https://webpack.js.org/concepts/targets/
When I change my app.js and main.css while webpack-dev-server is running, the bundle is updated.
But when i change the index.html the content is not refreshed; if I add a line to the HTML, the webpack-dev-server does not refresh anything on the page.
Here are my webpack.config.js and package.json files.
I hope you can help me.
webpack.config.js:
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var chalk = require('chalk');
var env = process.env.WEBPACK_ENV;
var host = 'localhost';
var port = '8080';
var config = {
devtool: 'source-map',
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://' + host + ':' + port +'/',
'./src/app.js'
],
output: {
path: __dirname + '/dist',
filename: 'bundle.js'
},
module : {
loaders: [
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.html$/,loader: 'file?name=[name].[ext]' }
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new CleanWebpackPlugin(['dist'], {
root: __dirname,
verbose: true,
dry: false
})
]
};
if (env === 'dev') {
new WebpackDevServer(webpack(config), {
contentBase: './dist/',
stats: {colors: true},
hot: true,
debug: true
}).listen(port, host, function (err, result) {
if (err) {
console.log(err);
}
});
console.log('-------------------------');
console.log(chalk.bold.white('Local web server runs at ') + chalk.green('http://' + host + ':' + port));
console.log('-------------------------\n\n');
}
module.exports = config;
package.json:
{
"name": "webpack-skeleton",
"version": "1.0.0",
"description": "webpack skeleton",
"main": "bundle.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "WEBPACK_ENV=dev ./node_modules/.bin/webpack --watch --inline"
},
"author": "Jose Roa",
"license": "ISC",
"devDependencies": {
"chalk": "^1.1.3",
"clean-webpack-plugin": "^0.1.9",
"css-loader": "^0.23.1",
"file-loader": "^0.8.5",
"style-loader": "^0.13.1",
"webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1"
}
}
My directory structure:
css
main.css
dist
bundle.js
bundle.js.map
index.html
node_modules
src
app.js
sum.js
package.json
index.html
node_modules
webpack.config.js
Every file inside the dist directory is generated by webpack.
add the HtmlWebpackPlugin
link: https://www.npmjs.com/package/html-webpack-plugin
add
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
]
};
It can be due to your IDE -- see webpack dev server
Working with editors/IDEs supporting “safe write”... This behaviour causes file watcher to lose the track because the original file is removed. In order to prevent this issue, you have to disable “safe write” feature in your editor.
You can try this workaround for auto reloading while developing an app. Add to your entry point ('./src/app.js'):
require('../index.html'); //workround to reload page on index.html changes