I am trying to use Gulp to generate a file,
gulphile.js
const elixir = require('laravel-elixir');
require('laravel-elixir-vue-2');
elixir(mix => {
mix.sass('app.scss')
.webpack('app.js');
});
app.js
window._ = require('lodash');
window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');
window.Vue = require('vue');
require('vue-resource');
When I run the command gulp watch Gulp generates a file with a very big size (about 3mb), and the file does not look like it is minimized.
It looks something like this:
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 11);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports) {
eval("var g;\r\n\r\n// This works in non-strict
mode\r\ng = (function() { return this; })();\r\n\r\ntry {\r\n\t// This
works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")
() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window refer
How can I fix it to generate the file correctly minimized?
Use the --production option to run the tasks to minimize the css and js files.
gulp --production
This option works with watch, as well:
gulp watch --production
Related
Sorry if this question has already been answered, but there are so many post with this error name and a different context, that I could find the answer to this particular case.
I am using Javascript ES6 modules, and I am trying to 'compile' all my javascript files into one minified file. I am using Gulp for that. I have 3 js files (gulpfiles, an index file that require ma class, and the class file). I also have an HTML file to test the minified js file. Here is what my project looks like :
// File : gulpfile.js
const { src, dest, task, watch, series, parallel } = require('gulp');
var uglify = require('gulp-uglify')
var babelify = require('babelify')
var browserify = require('browserify')
var source = require('vinyl-source-stream')
var buffer = require('vinyl-buffer')
var rename = require('gulp-rename')
const jsSRC = './classes/'
const jsDEST = './output/'
const jsFILES = ['index.js']
function js(done) {
jsFILES.map( function (entry) {
return browserify({
entries: [jsSRC + entry]
})
.transform( babelify, { presets: ['#babel/preset-env'] } )
.bundle()
.pipe( source( entry) )
.pipe( rename({ extname: '.min.js'}) )
.pipe( buffer() )
.pipe( uglify() )
.pipe( dest( jsDEST ))
})
done()
}
task('js',js)
task('default', parallel(js))
// File : classes/Logger.js
class Logger{
constructor(msg){
console.log(msg)
}
}
export default Logger ;
// File : classes/index.js
import Logger from './Logger.js'
exports = { Logger }
var l = new Logger('Hello') // This should log 'Hello' in the console
// File : demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Demo</title>
</head>
<body>
<script src="./output/index.min.js"></script>
</body>
</html>
(I used the command npm install #babel/core #babel/preset-env babelify browserify gulp gulp-cli gulp-rename gulp-uglify vinyl-buffer vinyl-source-stream to install all the dependecies)
So, here is the problem. When I open the HTML file in a browser, I get the 'Hello' displayed in the console, because it is triggered by the var l = new Logger('Hello') line in the index.js file. But if I type the exact same thing in the console, I get this error Uncaught ReferenceError: Logger is not defined
This is probably a noob mistake. Do someone knows why I cannot use the Logger class from my page with the minified js ? And what can I do to make my class usable from the minified js file ?
Thank you !
(If there is a problem with the question, duplicated question or whatever, just tell me and I will close/delete it)
I have installed Resumablejs with Yarn and I see it in node_module folder.
Webpack.config.js
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')
/*
* ENTRY CONFIG
*
* Add 1 entry for each "page" of your app
* (including one that's included on every page - e.g. "app")
*
* Each entry will result in one JavaScript file (e.g. app.js)
* and one CSS file (e.g. app.css) if your JavaScript imports CSS.
*/
.addEntry('app', './assets/js/app.js')
....
var config = Encore.getWebpackConfig();
var path = require('path');
config.resolve.alias = {
'jquery': path.resolve(__dirname, 'node_modules/jquery/src/jquery'),
'resumablejs': path.resolve(__dirname, 'node_modules/resumablejs/resumable')
};
module.exports = config;
package.json
"dependencies": {
...
"resumablejs": "^1.1.0",
...
}
app.js
/*
* Welcome to your app's main JavaScript file!
*
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
// any CSS you require will output into a single css file (app.css in this case)
require('../css/app.scss');
const $ = require('jquery');
global.$ = global.jQuery = $;
require('resumablejs');
...
import './EntriesJs';
EntriesJs
import AppScripts from './js/appScripts';
export {
AppScripts
}
In my app.js i have declare it require('resumablejs'); and then in my file I want to use it like this:
module.exports = function (uploadJs) {
return filesUploadScript();
};
function filesUploadScript() {
(function () {
console.log('js loaded...');
var uploaderWidgetProperties = $('#_f-uploader-widget-properties');
var r = new Resumable({ ... });
but at this point I am getting the following error:
Uncaught ReferenceError: Resumable is not defined
I have a hard time understanding Webpack so any help will be great.
I want to prepend a JavaScript string to every module required in my code and compiled by Webpack.
For example, if my entry.js file looks like this:
import _ from 'lodash';
import $ from 'jquery';
import init from './init.js';
init();
I want my output.js bundle to consist of something like this:
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
// code for lodash module below
}
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
// code for jquery module below
}
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
// code for init.js module below
}
function(module, exports, __webpack_require__) {
// prepended JavaScript goes here
var _lodash = __webpack_require__(1);
var _jquery = __webpack_require__(2);
init();
}
I tried writing a simple loader, and it worked, except that it didn't include modules from node_modules since I'm excluding those from my /\.js$/ rule.
So I suspect I need to use a plugin. This is what I have so far:
var pluginName = "PrependJSPlugin";
var apply = (options, compiler) => {
compiler.hooks.compilation.tap(pluginName, compilation =>
compilation.hooks.afterOptimizeModules.tap(pluginName, modules => {
modules.forEach(mod => {
if (mod.resource !== void 0 && mod.resource.includes(".js")) {
var contId = "__WBP_PREPEND__";
var script = `
;var el = document.createElement('pre');
el.innerHTML = '${mod.resource}';
var container = document.getElementById('${contId}');
if (!container) {
container = document.createElement('div');
container.id = '${contId}';
container.appendChild(el);
document.getElementsByTagName('body')[0].appendChild(container);
} else {
container.appendChild(el);
}
`;
mod._source._value = script + mod._source._value;
}
});
})
);
};
module.exports = function(options) {
return {
apply: apply.bind(this, options)
};
};
For the most part, it seems like it's appending it correctly but the compiled output is getting corrupted somehow and I see syntax errors all over the place. I'm definitely doing something I shouldn't be doing with that _source property.
Can someone point me in the right direction?
Why do I want to do this?
This is not something that will go into production. I'm trying to debug a PhantomJS v1 error occurring in a third party service I use for rendering a PDF from an Angular page. Yikes, I know!
I'm catching errors with window.onerror and appending it to the body so they're displayed in the rendered PDF. Unfortunately, the errors don't include source file nor line numbers. So I'm trying to display the name of every module before it runs hoping to see at which one the JavaScript stops executing.
When I run "gulp style" from the command line, Gulp runs, and, subsequently, gulp-jscs runs, but the latter seems to be unable to detect the rules defined in the jscs config file (.jscsrc). But, if I run jscs from the command line, then jscs does detect the config file's rules. Any idea what the deal could be?
Here's my gulp file:
(function() {
"use strict";
var gulp = require("gulp");
var jshint = require("gulp-jshint");
var jscs = require("gulp-jscs");
var jsFiles = ["*.js", "src/**/*.js"];
gulp.task("style", function () {
console.log("Running the style task.");
return gulp.src(jsFiles)
.pipe(jshint())
.pipe(jshint.reporter("jshint-stylish", {
verbose: true
}))
.pipe(jscs({configPath: "./.jscsrc"}));
});
})();
You need a reporter (just like jshint has one):
var gulp = require("gulp");
var jshint = require("gulp-jshint");
var jscs = require("gulp-jscs");
var jsFiles = ["*.js", "src/**/*.js"];
gulp.task("style", function () {
console.log("Running the style task.");
return gulp.src(jsFiles)
.pipe(jshint())
.pipe(jshint.reporter("jshint-stylish", {
verbose: true
}))
.pipe(jscs({configPath: "./.jscsrc"}))
.pipe(jscs.reporter()); // << this line here
});
Other notes, (if you are running from cmd), Gulpfile.js you don't need to wrap it into anonymous function or use 'use strict'.
Example output:
[13:53:30] Using gulpfile C:\del\so\gulpjscs\Gulpfile.js
[13:53:30] Starting 'style'...
Running the style task.
[13:53:31] gulp-debug: Gulpfile.js
[13:53:31] gulp-debug: index.js
[13:53:31] gulp-debug: 2 items
Comments must start with a lowercase letter at C:\del\so\gulpjscs\index.js :
1 |// Invalid
--------^
2 |// valid
3 |
1 code style error found.
[13:53:31] Finished 'style' after 187 ms
If you're not sure how will current path ./ be taken into account you can always use path module to resolve, for example:
var path = require('path');
var configPath = path.resolve(path.join(__dirname, '.jscsrc'))
By default, browserify does not perform transforms on modules included from node_modules, i.e. with no path.
I made a quick github repo that illustrates it here. The index.js file that gets browserified looks like this:
var fs = require('fs');
var testmodule = require('testmodule');
var trg1 = document.getElementById("target1");
var trg2 = document.getElementById("target2");
trg1.innerHTML = fs.readFileSync(__dirname+"/something.txt");
trg2.innerHTML = testmodule();
testmodule looks like this:
var fs = require('fs');
exports = module.exports = function() {
return fs.readFileSync(__dirname+'/data.txt');
}
Using the brfs transform module, I want to be able to inline both calls to fs.readFileSync, but when I run browserify index.js -t brfs -o bundle.js, only the call in my main project gets inlined. Here is the bundle.js result:
;(function(e,t,n){function r(n,i){if(!t[n]){if(!e[n]){var s=typeof require=="function"&&require;if(!i&&s)return s(n,!0);throw new Error("Cannot find module '"+n+"'")}var o=t[n]={exports:{}};e[n][0](function(t){var i=e[n][1][t];return r(i?i:t)},o,o.exports)}return t[n].exports}for(var i=0;i<n.length;i++)r(n[i]);return r})({1:[function(require,module,exports){
// nothing to see here... no file methods for the browser
},{}],2:[function(require,module,exports){
var fs = require('fs');
var testmodule = require('testmodule');
var trg1 = document.getElementById("target1");
var trg2 = document.getElementById("target2");
trg1.innerHTML = "This is data from a file in the main project folder"; // TRANSFORMED
trg2.innerHTML = testmodule();
},{"fs":1,"testmodule":3}],3:[function(require,module,exports){
(function(__dirname){var fs = require('fs');
exports = module.exports = function() {
return fs.readFileSync(__dirname+'/data.txt'); // NO TRANSFORM
}
})("/node_modules/testmodule")
},{"fs":1}]},{},[2])
;
Got some help from substack (author of browserify) on this one. To specify if a module outside of a project requires transformations, you need to specify a browserify.transform array in your package.json. So for the example I gave above, the package.json file in the testmodule directory looks like this:
{
"name":"testmodule",
"version":"0.0.0",
"browserify": {
"transform": ["brfs"]
},
"main": "index.js"
}
You can also use browserify -g brfs instead of browserify -t brfs. g is a global transform (which applies to dependencies)