I've got two Gulp tasks in my gulpfile.js. It's used for a website.
The first one compiles with webpack the main js file, used on all pages of the site (mainly visuals), and combines it to a single file.
gulp.task('scripts', function(callback) {
let firstBuildReady = false;
function done(err, stats) {
firstBuildReady = true;
if (err) { // hard error, see https://webpack.github.io/docs/node.js-api.html#error-handling
return; // emit('error', err) in webpack-stream
}
gulplog[stats.hasErrors() ? 'error' : 'info'](stats.toString({
colors: true
}));
}
let options = {
output: {
publicPath: '/js/',
filename: isDevelopment ? '[name].js' : '[name]-[chunkhash:10].js'
},
watch: isDevelopment,
devtool: isDevelopment ? 'cheap-module-inline-source-map' : false,
module: {
loaders: [{
test: /\.js$/,
//include: path.join(__dirname, "app/src/scripts/modules"),
loader: 'babel-loader',
query: {
presets: ["env"]
}
}]
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
]
};
if (!isDevelopment) {
options.plugins.push(new AssetsPlugin({
filename: 'scripts.json',
path: __dirname + '/app/manifest',
processOutput(assets) {
for (let key in assets) {
assets[key + '.js'] = assets[key].js.slice(options.output.publicPath.length);
delete assets[key];
}
return JSON.stringify(assets);
}
}));
}
return gulp.src(jsSRC)
.pipe(plumber({
errorHandler: notify.onError(err => ({
title: 'Scripts',
message: err.message
}))
}))
.pipe(named(function(file){
return 'app'
}))
.pipe(webpackStream(options, null, done))
.pipe(gulpIf(!isDevelopment, uglify()))
.pipe(gulp.dest(jsDIST))
.on('data', function() {
if (firstBuildReady) {
callback();
}
});
});
The second one compiles each js module as a single file - some js scripts, used on special pages. These scripts are included only there where needed.
gulp.task('webpack', function(callback) {
let firstBuildReady = false;
function done(err, stats) {
firstBuildReady = true;
if (err) {
return;
}
gulplog[stats.hasErrors() ? 'error' : 'info'](stats.toString({
colors: true
}));
}
let options = {
output: {
publicPath: '/js/',
filename: isDevelopment ? '[name].js' : '[name]-[chunkhash:10].js'
},
watch: isDevelopment,
devtool: isDevelopment ? 'cheap-module-inline-source-map' : false,
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ["env"]
}
}]
},
plugins: [
new webpack.NoEmitOnErrorsPlugin()
]
};
if (!isDevelopment) {
options.plugins.push(new AssetsPlugin({
filename: 'webpack.json',
path: __dirname + '/app/manifest',
processOutput(assets) {
for (let key in assets) {
assets[key + '.js'] = assets[key].js.slice(options.output.publicPath.length);
delete assets[key];
}
return JSON.stringify(assets);
}
}));
}
return gulp.src('app/src/scripts/modules/*.js')
.pipe(plumber({
errorHandler: notify.onError(err => ({
title: 'Webpack',
message: err.message
}))
}))
.pipe(named())
.pipe(webpackStream(options, null, done))
.pipe(gulpIf(!isDevelopment, uglify()))
.pipe(gulp.dest(jsDIST))
.on('data', function() {
if (firstBuildReady) {
callback();
}
});
});
But I have to include Jquery in every single file for the second task, otherwise it's not compiled. But Jquery is included in the main app.js file.
How can I solve it?
Thanks
Since it sounds like you're using a somewhat exotic way of loading JS in your application (instead of approaches like require.ensure), your easiest option may be to use Webpack externals when building your individual modules. Your main script/page will have to ensure that jQuery is globally exposed (like under window.$ or window.jQuery). Then, for your webpack config, include something like this:
{
// ...
externals: {
jquery: '$'
}
}
This will substitute $ for all require('jquery') calls instead of including jquery in each JS bundle.
Related
I try to use sql.js-httpvfs library inside my project. However, I am not successed yet. I am not expert about node.js.
What I do?
Firstly, need to webpack.config to Gatsby for that I create gatsby-node.js file and add the below code inside it.
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
entry: "./src/index.js",
module: {
rules: [
{
test: "/.tsx?$/",
use: "ts-loader",
exclude: "/node_modules/",
},
],
},
output: {
filename: "bundle.js",
},
devServer: {
publicPath: "/dist",
},
});
};
Inside my index.js page, I add the code;
import { createDbWorker } from "sql.js-httpvfs";
const workerUrl = new URL(
"sql.js-httpvfs/dist/sqlite.worker.js",
import.meta.url
);
const wasmUrl = new URL("sql.js-httpvfs/dist/sql-wasm.wasm", import.meta.url);
function load() {
const worker = createDbWorker(
[
{
from: "inline",
config: {
serverMode: "full",
url: "../myTestDb.sqlite3",
requestChunkSize: 4096,
},
},
],
workerUrl.toString(),
wasmUrl.toString()
);
const result = worker.db.query(`select * from districts`);
document.body.textContent = JSON.stringify(result);
}
load();
But I got error.
There is no any created bundle.js or folder like dist.
I am following a course on Udemy which is about Wordpress development. Following the course I came up with this problem, I was trying to add google maps to a custom post type, for that I needed to update javascript file. But whenever I am running 'gulp scripts', this error occurs. I have no idea about node, gulp, webpack. I am just following the course. I looked up on the internet for a long time on this issue but found nothing.
I am using XAMPP. And before this, 'gulp watch' was working fine and php scripts were getting updated just fine.
gulpfile.js:-
var gulp = require('gulp'),
settings = require('./settings'),
webpack = require('webpack'),
browserSync = require('browser-sync').create(),
postcss = require('gulp-postcss'),
rgba = require('postcss-hexrgba'),
autoprefixer = require('autoprefixer'),
cssvars = require('postcss-simple-vars'),
nested = require('postcss-nested'),
cssImport = require('postcss-import'),
mixins = require('postcss-mixins'),
colorFunctions = require('postcss-color-function');
gulp.task('styles', function() {
return gulp.src(settings.themeLocation + 'css/style.css')
.pipe(postcss([cssImport, mixins, cssvars, nested, rgba, colorFunctions, autoprefixer]))
.on('error', (error) => console.log(error.toString()))
.pipe(gulp.dest(settings.themeLocation));
});
gulp.task('scripts', function(callback) {
webpack(require('./webpack.config.js'), function(err, stats) {
if (err) {
console.log(err.toString());
}
console.log(stats.toString());
callback();
});
});
gulp.task('watch', function(done) {
browserSync.init({
notify: false,
proxy: settings.urlToPreview,
ghostMode: false
});
gulp.watch('./**/*.php', function(done) {
browserSync.reload();
done();
});
gulp.watch(settings.themeLocation + 'css/**/*.css', gulp.parallel('waitForStyles'));
gulp.watch([settings.themeLocation + 'js/modules/*.js', settings.themeLocation + 'js/scripts.js'], gulp.parallel('waitForScripts'));
done();
});
gulp.task('waitForStyles', gulp.series('styles', function() {
return gulp.src(settings.themeLocation + 'style.css')
.pipe(browserSync.stream());
}))
gulp.task('waitForScripts', gulp.series('scripts', function(cb) {
browserSync.reload();
cb()
}))
webpack.config.js:-
const path = require('path'),
settings = require('./settings');
module.exports = {
entry: {
App: settings.themeLocation + "js/scripts.js"
},
output: {
path: path.resolve(__dirname, settings.themeLocation + "js"),
filename: "scripts-bundled.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
},
mode: 'development'
}
settings.js:
exports.themeLocation = '/wp-content/themes/fictional-university-theme/';
exports.urlToPreview = 'localhost/imuni';
I had the same error the solution is simple add a DOT before /wp-content/:
exports.themeLocation = './wp-content/themes/fictional-university-theme/';
exports.urlToPreview = 'localhost/imuni';
When I change styles in my .vue files and .css files, I dont' want the page to refresh, and I want the style auto change. But now page always refresh when I change the styles.
I'm using the vue-cli to generate the webpack config file.
as below
webpack.dev.conf.js
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: false })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
})
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
util.js
exports.cssLoaders = function (options) {
options = options || {}
const styleLoader = {
loader: 'style-loader',
options: {
sourceMap: options.sourceMap
}
}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [styleLoader, cssLoader, postcssLoader] : [styleLoader, cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
I have already add the style-loader, but it doesn't work at all.
the config is complicated and I don't know how to fix that.
webpack-dev-server 2.11.3
webpack 3.12.0
How i can specify different filename for different entry output?
For example:
module.exports = {
context: path.resolve(__dirname, 'assets'),
entry: {
vendor: ['react', 'react-dom', 'lodash', 'redux'],
app: './src/app.js'
}
output: {
path: path.resolve(__dirname, (isDevelopment) ? 'demo' : 'build'),
filename: (isDevelopment) ? '[name].js' : '[name][chunkhash:12].js'
}
}
To receive output like this
build
-- index.html
-- app.2394035ufas0ue34.js
-- vendor.js
So browser will cache vendor.js with all libraries. Since i don't plan to migrate to any major new release anytime soon and often.
And still being able to break cache for app.js with every update required.
is there some kind of option to set output as
output: {
app: {
...
},
vendor: {
...
},
}
Here is working code:
entry: {
'./build/app': './src/app.js',
'./build/vendor': VENDOR_LIBS // or path to your vendor.js
},
output: {
path: __dirname,
filename: '[name].[chunkhash].js'
},
Add this code into your webpack plugins array as last element of an array.
plugins: [
... // place our new plugin here
]
function() {
this.plugin("done", function(stats) {
const buildDir = __dirname + '/build/';
const fs = require('fs');
var vendorTempFileName = '';
new Promise(function(resolve, reject) {
fs.readdir(buildDir, (err, files) => {
files.forEach(file => {
if (file.substr(0,6) === 'vendor') {
resolve(file);
}
});
});
}).then(function(file) {
fs.rename( buildDir + file, buildDir + 'vendor.js', function(err) {
if ( err ) console.log('ERROR: ' + err);
});
});
});
}
Output should be as follows:
It is considered bad practice to leave your files without chunkhashes, due to browser caching.
For Webpack 4 I added a quick-and-dirty done hook to rename my service worker script:
// Plugin to rename sw-[chunkhash].js back to sw.js
class SwNamePlugin {
apply(compiler) {
compiler.hooks.done.tap("SW Name Plugin", (stats) => {
const swChunk = stats.compilation.chunks.find((c) => c.name === "sw");
fs.rename(path.resolve(outDir, swChunk.files[0]), `${outDir}/sw.js`);
});
}
}
plugins.push(new SwNamePlugin());
This obviates the warning DeprecationWarning: Tapable.plugin is deprecated. Use new API on .hooks instead you'd see following loelsonk's answer.
Somewhere in development this error started showing, I can't pinpoint where it comes from. The error is to 'broad' for my knowledge. I'm using webpack and gulp. If anyone can point me in the right direction.
I can post more code, but you'll need to tell me what files. The app works as it should, REST, pages loading, etc.. Only the css is not showing.
Starting gatling-rsync-deamon...
Starting containers...
Starting vagrant_redis_1
Starting vagrant_mongo_1
Starting vagrant_app_1
Connection to 127.0.0.1 closed.
launching stream...
[14:39:00] Requiring external module babel-register
[14:39:14] Using gulpfile /var/www/app/gulpfile.babel.js
[14:39:14] Starting 'set-dev-env'...
NODE_ENV will be set to development...
[14:39:14] Finished 'set-dev-env' after 310 μs
[14:39:14] Starting 'backend-watch'...
[14:39:14] Backend warming up...
[14:39:14] Starting 'frontend-watch'...
[14:39:15] Finished 'frontend-watch' after 694 ms
[14:39:15] Starting 'server'...
[14:39:15] Finished 'server' after 1.55 ms
Webpack-dev-server listening at localhost:9090.
module.js:340
throw err;
^
Error: Cannot find module '/var/www/app/build/bundle'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:945:3
[14:39:20] Finished 'backend-watch' after 5.25 s
[14:39:20] Starting 'dev'...
[14:39:20] Finished 'dev' after 3.46 μs
Hash: 5e15e9e5b2fd1c868120
Version: webpack 1.13.0
gulpfile.babel.js
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import gulp from 'gulp';
import gutil from 'gulp-util';
import nodemon from 'nodemon';
import path from 'path';
import jsdoc from 'gulp-jsdoc3';
import WebpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';
// import backendConfig from './config/webpack.backend.config.js';
// import frontendConfig from './config/webpack.frontend.config.js';
import configs from './config/webpack.config';
import jsdocConfig from './config/jsdoc.config';
const [frontendConfig, backendConfig] = configs;
const FRONTEND_PORT = 8085;
const BACKEND_PORT = 9090;
function onBuild(err, stats) {
if (err) {
throw new Error(err);
}
console.log(stats.toString());
}
// Default: list all tasks.
gulp.task('default', () => {
console.log('Available commands: dev, build');
});
// Start frontend
gulp.task('frontend', (done) => {
webpack(frontendConfig).run((err, stats) => {
onBuild(err, stats);
done();
});
});
// Start frontend watch
gulp.task('frontend-watch', () => {
const webpackDevserver = new WebpackDevServer(webpack(frontendConfig), {
publicPath: frontendConfig.output.publicPath,
stats: { colors: true },
historyApiFallback: true,
proxy: {
'*': `http://localhost:${BACKEND_PORT}`
}
});
webpackDevserver.listen(BACKEND_PORT, 'localhost', (err, result) => {
if (err) {
console.log(err);
}
else {
console.log(`Webpack-dev-server listening at localhost:${BACKEND_PORT}.`);
}
});
});
// Start backend
gulp.task('backend', (done) => {
webpack(backendConfig).run((err, stats) => {
onBuild(err, stats);
done();
});
});
// Start backend watch
gulp.task('backend-watch', (done) => {
gutil.log('Backend warming up...');
let firedDone = false;
webpack(backendConfig).watch(100, (err, stats) => {
if (!firedDone) { done(); firedDone = true; }
onBuild(err, stats);
nodemon.restart();
});
});
//
// gulp.task('run', ['set-dev-env', 'backend-watch'], () => {
// nodemon({
// execMap: {
// js: 'node'
// },
// script: path.join(__dirname, 'build/backend'),
// ignore: ['*'],
// watch: ['foo/'],
// ext: 'noop'
// }).on('restart', () => {
// console.log('Patched!');
// });
// });
// Set NODE_ENV to development
gulp.task('set-dev-env', () => {
console.log('NODE_ENV will be set to development...');
process.env.NODE_ENV = 'development';
});
// Set NODE_ENV to production
gulp.task('set-prod-env', () => {
console.log('NODE_ENV will be set to production...');
process.env.NODE_ENV = 'production';
});
// Start server
gulp.task('server', () => {
nodemon({
execMap: {
js: 'node'
},
script: path.join(__dirname, 'build/bundle'),
ignore: ['*'],
watch: ['foo/'],
ext: 'noop'
}).on('restart', () => {
console.log('Server restarted!');
});
});
// Generate docs
gulp.task('docs', (cb) => {
// gulp.src(['README.md', './client/**/*.js', './server/**/*.js'], { read: false })
// .pipe(jsdoc(jsdocConfig, cb));
});
// Build project
gulp.task('build', ['set-prod-env', 'build-js']);
// Build backend & frontend
gulp.task('build-js', ['backend', 'frontend']);
// Watch backend & frontend
gulp.task('watch', ['backend-watch', 'frontend-watch']);
// Start development session
gulp.task('dev', ['set-dev-env', 'backend-watch', 'frontend-watch', 'server']);
webpack.config
import webpack from 'webpack';
import path from 'path';
import fs from 'fs';
import HtmlWebpackPlugin from 'html-webpack-plugin';
const embedFileSize = 50000;
const nodeModules = {};
fs.readdirSync('node_modules')
.filter(module => {
return ['.bin'].indexOf(module) === -1;
})
.forEach(mod => {
nodeModules[mod] = 'commonjs ' + mod;
});
const frontendConfig = {
entry: [
'webpack-hot-middleware/client',
path.join(__dirname, '../client/index.js')
],
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'build', 'public')
},
devtool: 'sourcemap',
plugins: [
new HtmlWebpackPlugin({
template: './client/public/index.html',
inject: 'body',
filename: 'index.html'
}),
new webpack.ProvidePlugin({
'Promise': 'es6-promise',
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
'__DEV__': JSON.stringify(process.env.NODE_ENV)
})
],
module: {
preloaders: [
{ test: /\.js$/, loader: 'eslint'}
],
loaders: [
{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.json?$/,
loader: 'json'
},
{
test: /\.css$/,
loader: 'style-loader!css-loader?modules&&importLoaders=1&localIdentName=[name]---[local]---[hash:base64:5]!postcss-loader'
},
{
test: /\.less$/,
loader: "style!css!less"
},
{ test: /\.svg/,
loader: 'url?limit=' + embedFileSize + '&mimetype=image/svg+xml'
},
{ test: /\.png$/,
loader: 'url?limit=' + embedFileSize + '&mimetype=image/png'
},
{ test: /\.jpg/,
loader: 'url?limit=' + embedFileSize + '&mimetype=image/jpeg'
},
{ test: /\.gif/,
loader: 'url?limit=' + embedFileSize + '&mimetype=image/gif'
},
{
test: /\.(otf|eot|ttf|woff|woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url?limit=' + embedFileSize
}
]
},
resolve: {
extensions: ['', '.js', '.jsx', '.json', '.css']
},
};
const serverConfig = {
entry: './server/server.js',
output: {
path: path.join(__dirname, '../build'),
filename: 'bundle.js'
},
devtool: 'sourcemap',
target: 'node',
// do not include polyfills or mocks for node stuff
node: {
console: false,
global: false,
process: false,
Buffer: false,
__filename: false,
__dirname: false
},
externals: nodeModules,
plugins: [
// enable source-map-support by installing at the head of every chunk
new webpack.BannerPlugin('require("source-map-support").install();',
{raw: true, entryOnly: false})
],
module: {
loaders: [
{
// transpile all .js files using babel
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel'
}
]
}
};
export default [frontendConfig, serverConfig];
My answer for now is based on your pasted code. When I get more info, then I will edit this answer.
Im not sure If I can find remotely correct solution for you. But your problem is probably with public path which is added to webpack and to WebpackDevServer. WebpackDevServer doesn't see your js code which is bundled in bundle.js
Change your target to "web" instead of node. You should compile for a web type of environment most likely and not a node.js like environment.
target: 'web',