Ignore certain .js files with webpack dev server running --hot - javascript

I have the need to import some javascript files as pure text with webpack.
All the files have a specific extension say: .mytype.js.
I have created a loader for these files using:
module.loaders = [{
test: /\.mytype.js?$/,
exclude: /(node_modules|bower_components|public\/)/,
loader: "mytype-loader"
}, ....]
I have regstered an alias to resolve my own loader
resolveLoader : {
alias : {
'mytype-loader' : path.resolve(__dirname, 'myloader.js')
}
}
At the moment myloader.js looks like this:
module.exports = source => {
console.log(source)
return(source)
}
For my dev server I have the following setup:
devServer: {
watchOptions : {
// I THOUGHT THIS WOULD STOP HOTLOAD CODE BEING ADDED??!
ignored : path.resolve(__dirname, 'mytypeFiles')
},
contentBase: CONTENT_BASE,
noInfo: true,
hot: true,
inline: true,
port: PORT,
headers : { 'Access-Control-Allow-Origin' : 'http://localhost:8888'},
host: HOST
},
All of my files with extension .mytype.js are in the mytypeFiles directory. The problem is that when I run this I get the following output from the loaders console.log
'use-strict';
function run(args, resources, meta) {
// a bunch of my code
}
;
var _temp = function () {
if (typeof __REACT_HOT_LOADER__ === 'undefined') {
return;
}
__REACT_HOT_LOADER__.register(run, 'run', 'D:/manatee-latest/manatee/src/bandicoot/resource-api/bandicoot-functions/run.bandicoot.js');
}();
However use-strict; and everything after the first function definition (which is mine) has been attached. How do I stop this hot loader code from being pre & post-fixed to my source?
Thanks in advance!

Related

Webpack Devserver: Open page in browser without typing '.html'

I'm making a plain, static site (HTML/CSS/JS) with Webpack that I intend to eventually deploy to s3. I have my final HTML files exported to the root of my dist folder like, index.html, foo.html, bar.html.
When I go to localhost:9000, my index loads as expected. For foo and bar I have to type the file extension like /foo.html and /bar.html for those pages to load. Is there a setting that I'm missing that will allow me to simply type /foo and /bar in the browser and have the intended pages load?
One way I found for individual pages, is to specify a proxy using devServer.proxy. For /foo and /bar, this would look like that:
const path = require("path");
module.exports = {
...
devServer: {
static: {
directory: path.resolve(__dirname, 'dist')
},
port: 3000,
open: false,
hot: true,
proxy: {
'/foo': {
target: 'http://localhost:3000/foo.html',
pathRewrite: { '^/foo': '' }
},
'/bar': {
target: 'http://localhost:3000/bar.html',
pathRewrite: { '^/bar': '' }
}
}
}
}
Check the DevServer documentation for more options.
In addition to Nikolai's answer, in case you need your local dev server to serve urls w/o extensions in router history mode, just use the following:
historyApiFallback: {
rewrites: [
{ from: /^\/$/, to: '/views/landing.html' },
{ from: /^\/subpage/, to: '/views/subpage.html' },
{ from: /./, to: '/views/404.html' },
],
},
Source: https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback

Want to use either of the 2 different .js files depending upon webpack build mode

This is my first question here.
I have two scripts: script.js and script-dev.js
Both scripts are located in 'static' folder(I am using NUXTJS)
Now, when webpack production build is used, ONLY script.js should be used and script-dev.js should be excluded/not used (sorry if i am using any incorrect term)
Similarly, for webpack development build, ONLY script-dev.js should be used and script.js should be excluded/not used.
(I am doing so because I will be using two diff API Urls in both files and script-dev.js will be used only for testing code in development. )
I have a nuxt.config.js file in root folder.
Can anyone please help me how can I modify the nuxt.config.js (or any other way you know) to achieve the above result.
here is my current nuxt.config.js and I have extended the webpack config as shown below (sorry for the improper formatting):
export default {
telemetry: false,
mode: 'universal',
server: {
host: '0.0.0.0',
port: 3000,
},
env: {
API_URL: process.env.API_URL,
},
serverMiddleware: [
{
path: '/r',
handler: '~/api/redirector.js',
},
],
build: {
extend(config, ctx) {
if (ctx.isDev) {
config.module.rules.push({
test: /.js$/,
exclude: [path.resolve(__dirname, 'static/script.js')],
})
} else {
config.module.rules.push({
test: /.js$/,
exclude: [path.resolve(__dirname, 'static/script-dev.js')],
})
}
},
},
}

'this is undefined' when requiring Tween.js with Webpack

I am using Webpack to compile all my JS into one file. The main file has this line in it:
import Tween from 'tween.js'
When I compile my file and open the HTML file that includes the result JS file in my browser, I am getting this error:
TypeError: this is undefined
and the browser console points at these lines of code:
// Include a performance.now polyfill
(function () {
// In node.js, use process.hrtime.
if (this.window === undefined && this.process !== undefined) { // it points to this line of code
TWEEN.now = function () {
var time = process.hrtime();
// Convert [seconds, microseconds] to milliseconds.
return time[0] * 1000 + time[1] / 1000;
};
}
I'm pretty sure that this import line cause if I comment out everything else, this error is still thrown, and if I comment out only this line, everything is working.
If I include the script directly into my HTML file, everything is okay, so I guess that's the Webpack issue.
Here is my Webpack config:
{
name: 'all scripts',
entry: {
'main': ['babel-polyfill', path.join(__dirname, 'clientside', 'client.js')],
},
output: {
path: path.join(__dirname, 'public'),
filename: '[name].js'
},
module:
{
loaders: [
{ test: /\.js$/,
loader: 'babel',
query: { presets:['es2015', 'stage-0'] }
}
],
},
}
What am I doing wrong?

Sourcemap generated from Gulp, not working as expected

So my app is running off a concatenated admin.bundle.js file. I'm using webpack to manage the modules, and then using gulp-webpack to import my webpack config, then run the sourcemap code:
gulp.task('webpack', function() {
return gulp.src('entry.js')
.pipe(webpack( require('./webpack.config.js') ))
.pipe(sourcemaps.init())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('app/assets/js'));
});
My Webpack config
var webpack = require('webpack');
module.exports = {
entry: "./entry.js",
output: {
pathinfo: true,
path: __dirname,
filename: "admin.bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
};
The problem is when I'm testing my app with ChromeDev tools, the break points in the individual app modules won't work. They only work when I look at the source for admin.bundle.js this isn't ideal as I need to search for a specific line in the code to goto :( instead of just having the break point happen inside of the module itself, which makes it easier and faster to debug.
Below the debugger is stopped on a function inside of the concatenated admin.bundle.js file
There is the tagsDirective.js module, this is where I expect the break point to happen :(
Anyone run into this problem before with Webpack and Gulp?
Screenshot of part of the admin.bundle and the map file:
Ah figured it out, I moved the sourcemap generation code back into webpack, and out of Gulp:
var webpack = require('webpack');
var PROD = JSON.parse(process.env.PROD_DEV || '0');
module.exports = {
entry: "./entry.js",
devtool: "source-map",
output: {
devtoolLineToLine: true,
sourceMapFilename: "admin.bundle.js.map",
pathinfo: true,
path: __dirname,
filename: PROD ? "admin.bundle.min.js" : "admin.bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
},
plugins: PROD ? [
new webpack.optimize.UglifyJsPlugin({minimize: true})
] : []
};
gulp.task('webpack', function() {
return gulp.src('entry.js')
.pipe(webpack( require('./webpack.config.js') ))
// .pipe(sourcemaps.init())
// .pipe(sourcemaps.write('./'))
.pipe(gulp.dest('app/assets/js'));
});

Webpack HotModuleReplacement css

I am trying to use webpack as a replacement for gulp and livereload workflow. I have set up HotModuleReplacement Plugin and it works correctly for JS files but I can't get it to work with SCSS files. It is compiling the SCSS to CSS properly but I have to manually refresh the browser each time to get the style changes to show. I am thinking it maybe a mistake in how I have the config set up or something like that.
I have this server.js file that is running things:
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
noInfo: true,
stats: { colors: true }
}).listen(3000, 'localhost', function (err, result) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3000');
});
and this webpack.config.js
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var cssLoaders = ['css-loader'];
var jsLoaders = ['react-hot', 'babel'];
var scssLoaders = cssLoaders.slice(0);
scssLoaders.push('sass-loader?includePaths[]=' + path.resolve(__dirname, './styles'));
module.exports = {
devtool: 'sourcemap',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./scripts/index'
],
output: {
path: path.join(__dirname, './build'),
filename: 'bundle.js',
publicPath: '/build/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin('styles.css')
],
resolve: {
extensions: ['', '.js', '.jsx', '.scss']
},
module: {
loaders: [
{ test: /\.js?$/, loaders: jsLoaders, include: path.join(__dirname, 'scripts'), exclude: /node_modules/},
{ test: /\.css$/ ,loader: ExtractTextPlugin.extract('style-loader', cssLoaders.join('!')) },
{ test: /\.js$/, loader: "eslint-loader", exclude: /node_modules/ },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract('style-loader', scssLoaders.join('!')) }
]
}
};
In one of my js files I just have a call to the SCSS file like this:
require('../styles/app');
I have looked into the docs for this and there are some instructions that suggest that you need to manually opt in for each module but I am not sure why that is, where to add that code etc
What I am trying to do seems like a pretty straight forward use case so is this supported or will I still also have to use gulp and live reload just for styles?
Unfortunately the extract-text-webpack-plugin, which is extracting all your styles to a CSS file, doesn't work well with hot-reloading (see https://github.com/webpack/extract-text-webpack-plugin/issues/30).
This hacky bit of JavaScript will reload all stylesheets any time it detects any hot reload event happening. It can get annoying, though, and works better on Firefox than on Chrome - Chrome seems to delay applying the new stylesheet until you focus the browser tab.
if (module.hot) {
$(window).on("message onmessage", function(event) {
if (typeof event.originalEvent.data === "string" && event.originalEvent.data.indexOf("webpackHotUpdate") === 0) {
console.log("Reloading style sheets...");
document.styleSheets.forEach(function (sheet) {
if ((sheet.href || "").indexOf('localhost') !== -1) {
sheet.ownerNode.href = sheet.href;
}
});
}
});
}
There may be some way to hook further into the guts of the hot reloading code, but I haven't looked into it.
As mentioned above, extract-text-webpack-plugin is not working properly with hot replacement, unfortunately :( But there's one more option how to solve this issue while development. That's disable property in extract plugin settings.
Modify a bit your config as described below:
plugins: [
new ExtractTextPlugin('styles.css', {disable: process.env.NODE_ENV !== 'production'})
]
That will disable usage of ExtractTextPlugin while development (I mean if you run it anyhow but NODE_ENV=production webpack, or any other rule you prefer) and bundle your styles within js.
Also mind importing your style file in the entry point. Hope that works. Cheers ;)
PS. Also you can avoid combining your entry point with 'webpack-dev-server/client?http://localhost:3000', 'webpack/hot/only-dev-server' and adding new webpack.HotModuleReplacementPlugin() to plugins manually just by running webpack dev server with additional params
webpack-dev-server --inline --hot
inline stands for webpack-dev-server/client and --hot for webpack-dev-server/client

Categories