How to make gulp-babel resolve the imports of a js file. Because right now it is running without error in visual studio but the imports are not resolved. Does the source directory of modules to import need to be specified - how to do that in the gulpfile.js?
gulpfile.js
"use strict";
var gulp = require("gulp");
var babel = require("gulp-babel");
gulp.task("js", function () {
return gulp.src('./wwwroot/js/app.js')
.pipe(babel())
. pipe(gulp.dest('./wwwroot/js/babel'));
});
app.js:
import { MDCRipple } from '#material/ripple';
import { MDCTextField } from '#material/textfield';
const username = new MDCTextField(document.querySelector('.username'));
const password = new MDCTextField(document.querySelector('.password'));
new MDCRipple(document.querySelector('.cancel'));
new MDCRipple(document.querySelector('.next'));
This solved the issue:
https://github.com/babel/babelify/issues/247
In my current understanding the issue was: the dependencies are not being transpiled to a javascript version understandable by browserify.
[What worked]
gulpfile.js:
"use strict";
var gulp = require("gulp");
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var babelify = require('babelify');
gulp.task("js", function () {
browserify('./wwwroot/js/app.js')
.transform("babelify", {
global: true,
presets: ["es2015", "es2016", "stage-0"],
ignore: /\/node_modules\/underscore/
})
.bundle()
.pipe(source('babel.js'))
.pipe(gulp.dest('./wwwroot/js'));
});
package.json:
{
"version": "1.0.0",
"name": "asp.net",
"private": true,
"devDependencies": {
"babel-core": "6.26.3",
"gulp": "3.9.1",
"browserify": "15.0.0",
"babelify": "8.0.0",
"babel-preset-es2015": "6.24.1",
"babel-preset-es2016": "6.24.1",
"babel-preset-stage-0": "6.24.1",
"vinyl-source-stream": "2.0.0",
"material-components-web": "0.28.0"
}
}
Related
So I'm a big fan of webpack but I have to use only gulp in this work I'm doing and I'm living a nightmare configuring this to actually start working.
On my index.js there is just import Swiper from 'swiper' And this error returns:
Uncaught TypeError: Failed to resolve module specifier "swiper".
Relative references must start with either "/", "./", or "../".
I'm using this configuration in my gulpfile :
const gulp = require('gulp');
const { src, dest, watch, series, parallel } = require('gulp');
const imagemin = require('gulp-imagemin');
const sourcemaps = require('gulp-sourcemaps');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const replace = require('gulp-replace');
const terser = require('gulp-terser');
const sass = require('gulp-sass')(require('sass'));
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const browsersync = require('browser-sync').create()
const paths = {
html: {
src: ['./src/**/*.html'],
dest: './dist/',
},
images: {
src: ['./src/images/**/*'],
dest: './dist/content/images/',
},
styles: {
src: ['./src/scss/**/*.scss'],
dest: './dist/css/',
},
scripts: {
src: ['./src/scripts/**/*.js'],
dest: './dist/js/',
},
cachebust: {
src: ['./dist/**/*.html'],
dest: './dist/',
},
};
function copyHtml() {
return src(paths.html.src).pipe(dest(paths.html.dest)).pipe(browsersync.stream())
}
function optimizeImages() {
return src(paths.images.src)
.pipe(imagemin().on('error', (error) => console.log(error)))
.pipe(dest(paths.images.dest))
.pipe(browsersync.stream())
}
function compileStyles() {
return src(paths.styles.src)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(dest('./src/css/'))
.pipe(postcss([autoprefixer(), cssnano()]))
.pipe(rename({ suffix: '.min' }))
.pipe(sourcemaps.write('.'))
.pipe(dest(paths.styles.dest))
.pipe(browsersync.stream())
}
function minifyScripts() {
return src(paths.scripts.src)
.pipe(sourcemaps.init())
.pipe(terser().on('error', (error) => console.log(error)))
.pipe(rename({ suffix: '.min' }))
.pipe(sourcemaps.write('.'))
.pipe(concat('bundle.js'))
.pipe(dest(paths.scripts.dest))
.pipe(browsersync.stream())
}
function cacheBust() {
return src(paths.cachebust.src)
.pipe(replace(/cache_bust=\d+/g, 'cache_bust=' + new Date().getTime()))
.pipe(dest(paths.cachebust.dest));
}
function browserSync() {
browsersync.init({
server: {
baseDir: './src'
}
})
}
function watcher() {
watch(paths.html.src, series(copyHtml, cacheBust));
watch(paths.images.src, optimizeImages);
watch(paths.styles.src, parallel(compileStyles, cacheBust));
watch(paths.scripts.src, parallel(minifyScripts, cacheBust));
}
exports.copyHtml = copyHtml;
exports.optimizeImages = optimizeImages;
exports.compileStyles = compileStyles;
exports.minifyScripts = minifyScripts;
exports.cacheBust = cacheBust;
exports.watcher = watcher;
exports.default = series(
parallel(copyHtml, optimizeImages, compileStyles, minifyScripts),
cacheBust,
parallel(watcher, browserSync)
);
My index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<script type="module" src="./scripts/index.js"></script>
</body>
</html>
package.json
{
"name": "frontend-challenge-heflerdev",
"version": "1.0.0",
"description": "Pontos importantes antes de iniciar",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "gulp"
},
"repository": {
"type": "git",
"url": "git+https://github.com/HeflerDev/frontend-challenge-junior.git"
},
"author": "HeflerDev",
"license": "MIT",
"bugs": {
"url": "https://github.com/HeflerDev/frontend-challenge-junior/issues"
},
"homepage": "https://github.com/HeflerDev/frontend-challenge-junior#readme",
"devDependencies": {
"autoprefixer": "^10.4.2",
"browser-sync": "^2.27.7",
"cssnano": "^5.1.0",
"eslint": "^8.10.0",
"gulp": "^4.0.2",
"gulp-concat": "^2.6.1",
"gulp-imagemin": "^7.0.0",
"gulp-postcss": "^9.0.1",
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.1.3",
"gulp-sass": "^5.1.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-terser": "^2.1.0",
"node": "^17.5.0",
"node-sass": "^7.0.1",
"postcss": "^8.4.8",
"sass": "^1.49.9"
},
"dependencies": {
"babel-core": "^6.26.3",
"babel-preset-es2015": "^6.24.1",
"require": "^2.4.20",
"swiper": "^8.0.7"
}
}
EDIT
Some of the folder structure
|dist/
|src/
|scripts
|index.js
|css
|scss
|images
|index.html
I tried a lot of things and I'm just banging my head on the wall, could someone help me?
Since you don't show the actual source file where you're importing swiper, I will assume that it's inside of this file on the client:
<script type="module" src="./scripts/index.js"></script>
From client-side JS files, you can't just do:
import Swiper from 'swiper'
As the error message from the browser says, you have to specify some type of path and you have to make sure your server is then serving the swiper module from that path.
Probably you want to do something like:
import Swiper from '/scripts/swiper'
since you rarely want to use relative paths for serving files on the client. And, then you also have to configure your server to respond to the request for /scripts/swiper to serve the swiper module.
Remember that a nodejs web server does not serve ANY files by default. You have to configure it to serve any file you want to server back to the client. You can often use something like express.static() to serve a whole directory or directory hierarchy of files with one statement, but you have to configure that properly.
Trying to minify a file and run it directly on the browser.
I'm using gulp & babel to do. The problem relies when I try to use async/await functions.
package.json
{
"#babel/core": "^7.11.6",
"#babel/plugin-transform-async-to-generator": "^7.12.1",
"#babel/plugin-transform-runtime": "^7.12.1",
"#babel/preset-env": "^7.11.5",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-concat": "^2.6.1",
...
}
The file
const i = async () => {
return await fetchAll();
};
Gulp/Babel config
const BabelConfig = {
presets: ['#babel/env'],
plugins: ['#babel/plugin-transform-async-to-generator']
};
const imports = ['./dev/**.*.js'];
return gulp.src(imports)
.pipe(babel(BabelConfig))
.pipe(concat('min.js'))
.pipe(gulp.dest(paths.dist.js));
This simply threw "regeneratorRuntime is not defined".
So I've tried adding "#babel/plugin-transform-runtime".
Gulp/Babel config
const BabelConfig = {
presets: ['#babel/env'],
plugins: ['#babel/plugin-transform-async-to-generator', '#babel/plugin-transform-runtime']
};
const imports = ['./dev/**.*.js'];
return gulp.src(imports)
.pipe(babel(BabelConfig))
.pipe(concat('min.js'))
.pipe(gulp.dest(paths.dist.js));
But now I get "require is not defined".
Does any one have any clues on how to achieve this?
You're almost there! I had a similar issue, the problem is that the compiled Gulp code includes "require" statements which aren't supported in most browsers. What fixed the issue for me was to add Webpack to the Gulp workflow to bundle everything:
npm install --save-dev webpack webpack-cli webpack-stream
in your gulpfile.js:
const {src, dest, watch} = require('gulp');
const gulpBabel = require('gulp-babel');
const webpack = require('webpack-stream');
const compiler = require('webpack');
function myES6Transpiler() {
return src('./es6/utilities.js')
.pipe(gulpBabel({
presets: ['#babel/preset-env', 'babel-preset-minify'],
plugins: ['#babel/transform-runtime', '#babel/plugin-transform-async-to-generator'],
}))
.pipe(webpack(require('./webpack.config-util.js'), compiler, function (err, stats) {
/* Use stats to do more things if needed */
}))
.pipe(dest('./js/'))
}
exports.myES6Transpiler = myES6Transpiler;
You also need to add a Webpack config file:
webpack.config.js
module.exports = {
mode: "production",
output: {
filename: "utilities.js"
}
}
When I run npm run build in my directory, to get all my files bundled into bundle.js, I find this error: ERROR in ./bundle.js from UglifyJs \n Unexpected token name «key», expected punc «;» [./bundle.js:8141,13].
So I went to bundle.js line 8141 and found this: for (let key in val) {
And therein lies the problem: let. Uglify cannot deal with let and const
So I've looked through the entire bundle.js file and the ONLY time let appears is literally right there, and a couple lines down, and I know specifically what package that code comes from: npm install clone-deep
None of the other packages I'm using are having this issue, they are all correctly converted from es6 before uglify runs, and I use let and const in my own code all the time. This one package only is causing me the issue.
Here's my package.json
{
"name": "jsx2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"author": "",
"license": "ISC",
"dependencies": {
"autobind-decorator": "^2.1.0",
"axios": "^0.18.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"classnames": "^2.2.5",
"clone-deep": "^4.0.1",
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-toastify": "^4.5.2",
"webpack": "^3.11.0"
},
"scripts": {
"dev": "webpack -d --watch",
"build": "webpack -p --config webpack.build.config.js"
}
}
And here's my webpack.build.config.js
// https://www.codementor.io/tamizhvendan/beginner-guide-setup-reactjs-environment-npm-babel-6-webpack-du107r9zr
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'out/');
var APP_DIR = path.resolve(__dirname, 'src/');
var config = {
entry: ['babel-polyfill', APP_DIR + '/App.jsx'],
output: {
path: BUILD_DIR,
filename: './bundle.js'
//https://cloud.githubusercontent.com/assets/593571/20785959/290f7fbc-b7b4-11e6-9ad2-7dafd7803552.png
//https://github.com/babel/babel-loader/issues/93
},
module : {
loaders : [
{
test : /\.jsx?/,
include : APP_DIR,
loader : 'babel-loader',
options: {
"presets" : ["env", "react"],
"plugins": ["transform-decorators-legacy"]
}
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
}
};
module.exports = config;
-- edit
Just to confirm, I did actually go into clone-deep index.js and change the lets to vars, and it all worked and I got no errors. I don't really consider that as a solution, because... there's no reason why this one package should have this error and nothing else. But it is definitely this one package that is the source of the issue.
Some npm packages have no es5 version. We have to accept this or use other packages.
If you want to continue to use clone-deep, you have to add this package to include property of your babel-loader config:
...
{
test : /\.jsx?/,
include : [APP_DIR, path.resolve(__dirname, 'node_modules', 'clone-deep')],
loader : 'babel-loader',
options: {
"presets" : ["env", "react"],
"plugins": ["transform-decorators-legacy"]
}
};
...
You can read more in this issue
I am currently discovering the module bundler "Webpack". I am trying to do something quite easy : I have a main.js entry and a bundle.js output. I use babel in order to translate in ES6.
My package.json :
{
"name": "me",
"version": "1.0.0",
"description": "Builder",
"main": "index.js",
"scripts": {
...
},
"author": "me",
"license": "ISC",
"devDependencies": {
"babel": "^6.23.0",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.5.2",
"babel-preset-es2015": "^6.24.1",
"gulp": "^3.9.1",
"lodash": "^4.17.4",
"webpack": "^3.0.0",
"webpack-stream": "^3.2.0"
},
"dependencies": {
"jquery": "^3.2.1"
}
}
Webpack.config.js :
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: path.resolve(__dirname, 'js/main.js'),
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
}
When I prompt webpack in the CLI, it works pretty well, a bundle.js file which is minified is created in the dist folder.
Now, I want to combine with Gulp
Here is my gulpfile.js :
var gulp = require('gulp');
var webpackS = require('webpack-stream');
gulp.task('default', function() {
return gulp.src('./app/js/main.js')
.pipe(webpackS( require('./app/webpack.config.js') ))
.pipe(gulp.dest('./app/dist/'));
});
When I enter gulp in the CLI, I have this error :
stream.js:74
throw er; // Unhandled stream error in pipe.
^
Error: bundle.js from UglifyJs
Unexpected token: name (_) [bundle.js:47,8]
However, when I remove the line new webpack.optimize.UglifyJsPlugin() from webpack.config.js and prompt gulp in the CLI it works perfectly !
I reinstalled all the npm packages but the problem is still here.
Does anybody have an idea ?
I would like to suggest you to don't mix webpack and gulp,
just create a script inside your package.json#scripts which runs webpack and then if you still want to exec webpack inside a gulp task you can do:
var exec = require('child_process').exec;
gulp.task('runWebpack', function (callback) {
exec('npm run webpack', callback);
})
How do you run the Webpack config? I assume by webpack path-to-config/webpack.config.js?
You have new webpack.optimize.UglifyJsPlugin() in your config, so by using webpack -p which executes the production mode, you get an error because UglifyJsPlugin is executed twice.
I guess the same happens with your Gulp setup.
However, the error message points to "_" not defined, which could be related to lodash. Maybe the import can't be resolved by Gulp?
However, I would not mix Gulp and Webpack. See the discussion here: Gulp + Webpack or JUST Webpack?
There is also an example using Webpack from within a gulp task.
I'm trying to setup VueJS components in a Node/Express app, I'm using Gulp with Browserify in order to import the components.
Problem:
My components aren't being exported correctly, after importing them, I try to debug with console.log, like this: import Home from './home.vue'; console.log(Home); and it returns this:
Object
_Ctor: VueComponent(options)
__proto__: Objec
Looking some working example (vue components), it should show method like: template, ready, data, etc in this object.
That's why I think my components are not being exported correctly, and the fact that my page is blank, nothing loads inside <div id="app"></div>.
Here are my setup:
Gulpfile.js:
/**
* Module Dependencies
*/
var gulp = require('gulp');
var gutil = require('gulp-util');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var notify = require('gulp-notify');
var minifycss = require('gulp-minify-css');
var concat = require('gulp-concat');
var plumber = require('gulp-plumber');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var nodemon = require('gulp-nodemon');
var vueify = require('vueify');
var browserify = require('browserify');
var es = require('event-stream');
var source = require('vinyl-source-stream');
var tap = require('gulp-tap');
var sourcemaps = require('gulp-sourcemaps');
var buffer = require('vinyl-buffer');
var babelify = require('babelify');
gulp.task('scripts', function () {
var b = browserify({
entries: 'scripts/store.js',
debug: true,
transform: [vueify, babelify.configure({presets: ["es2015"], plugins: ["add-module-exports"]})]
});
return b.bundle()
.pipe(source('scripts/store-app.js'))
.pipe(buffer())
.on('error', gutil.log)
.pipe(gulp.dest('./public/'));
});
/* Sass task */
gulp.task('sass', function () {
gulp.src('scss/**.scss')
.pipe(plumber())
.pipe(sass({
includePaths: ['scss'].concat()
}))
.pipe(gulp.dest('public/stylesheets'))
.pipe(rename({suffix: '.min'}))
.pipe(minifycss())
.pipe(gulp.dest('public/stylesheets'))
/* Reload the browser CSS after every change */
.pipe(reload({stream:true}));
});
/* Reload task */
gulp.task('bs-reload', function () {
browserSync.reload();
});
/* Prepare Browser-sync for localhost */
gulp.task('browser-sync', ['nodemon'], function() {
browserSync.init(['css/*.css', 'js/*.js'], {
/*
I like to use a vhost, WAMP guide: https://www.kristengrote.com/blog/articles/how-to-set-up-virtual-hosts-using-wamp, XAMP guide: http://sawmac.com/xampp/virtualhosts/
*/
proxy: 'localhost:3010',
port: 5000,
notify: true,
/* For a static server you would use this: */
//server: {
// baseDir: './public'
//}
});
});
gulp.task('nodemon', function (cb) {
var called = false;
return nodemon({
script: 'app.js',
ignore: [
'gulpfile.js',
'node_modules/'
]
})
.on('start', function () {
if (!called) {
called = true;
cb();
}
})
.on('restart', function () {
setTimeout(function () {
reload({ stream: false });
}, 1000);
});
});
/* Watch scss, js and html files, doing different things with each. */
gulp.task('default', ['sass', 'browser-sync'], function () {
/* Watch scss, run the sass task on change. */
gulp.watch(['scss/*.scss', 'scss/**/*.scss'], ['sass'])
/* Watch app.js file, run the scripts task on change. */
gulp.watch(['scripts/*.js'], ['scripts'])
/* Watch .html files, run the bs-reload task on change. */
gulp.watch(['*.html'], ['bs-reload']);
});
package.json:
{
"name": "myapp",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node app.js"
},
"browserify": {
"transform": [
"vueify",
"babelify",
"browserify-shim"
]
},
"browserify-shim": {
"./js/vendor/jquery.js": "$",
"three": "global:THREE"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.18.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.18.0",
"babelify": "^7.3.0",
"bootstrap": "^4.0.0-alpha.4",
"browser-sync": "^2.17.5",
"gulp": "^3.9.1",
"gulp-browserify": "^0.5.1",
"gulp-concat": "^2.6.0",
"gulp-minify-css": "^1.2.4",
"gulp-notify": "^2.2.0",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^2.3.2",
"gulp-sourcemaps": "^2.2.0",
"gulp-tap": "^0.1.3",
"gulp-uglify": "^2.0.0",
"gulp-util": "^3.0.7",
"tether": "^1.3.7",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
"vinyl-transform": "^1.0.0",
"vue": "^1.0.26",
"vue-hot-reload-api": "^2.0.6",
"vue-i18n": "^4.7.1",
"vue-resource": "^0.9.3",
"vue-router": "^0.7.13",
"vueify": "^8.7.0"
},
"dependencies": {
"basic-auth-connect": "^1.0.0",
"browserify": "^13.1.0",
"ejs": "^2.5.1",
"express": "^4.14.0",
"gulp-nodemon": "^2.2.1",
"i18n": "^0.8.3",
"nodemon": "^1.11.0",
"swagger-client": "^2.1.18",
"browserify-shim": "~3.2.0"
}
}
app.js
var Vue = require('vue');
var VueResource = require('vue-resource');
var VueRouter = require('vue-router');
// Components
import Home from '../home.vue';
console.log(Home);
Vue.use(VueRouter);
Vue.use(VueResource);
console.log(Vue);
var router = new VueRouter({
hashbang: true,
// history: true,
transitionOnLoad: true
});
router.map({
'/': { component: Home, name: 'root' }
});
var App = Vue.extend({
});
router.start(App, '#app');
home.vue
<script>
var Header = require('../header.vue');
export default {
data () {
},
ready () {
},
components: {
'app-header': Header
}
}
</script>
<template>
<div>
Home
</div>
</template>
index.html.ejs
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="bundle.js"></script>
</body>
</html>
Notes:
1 - If I change my app.js using a inline component like the example below, it works:
var Foo = {
template: '<p>This is foo!</p>'
}
router.map({
'/': { component: Foo, name: 'root' },
});
More one reason I think the problem is on bundled components. In order to do bundle these components and get this structure to work I'm using some tools like: Browserify, Babel, Vueify, Babelify.