WebSocket shim error with Webpack - websocket

I'm having trouble creating a WebSocket object on a webpack project. When I call new WebSocket("") it appears as though I get back the constructor as opposed to a new object of that constructor. I have a simple web page that does not use webpack and there everything works fine. Stepping through the working version with the Chrome debugger looks like this:
I cannot step into the WebSocket constructor, it just jumps to the next line. Now with my webpacked app it does step into the constructor where I see this:
and upon stepping out I see this:
I'm really not sure what I'm doing wrong here, how can I fix this? The app is not to be hosted by a webpack server, I'm only using webpack for packaging. All of this is on Chrome on OSX; below is my webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
// 'webpack-dev-server/client?http://localhost:3000',
// 'webpack/hot/only-dev-server',
'./src/turborabbit'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
}]
}
};
EDIT:
The module I'm importing and having trouble with is rserve. I have a workaround which is the ugliest thing I have ever done. The module only uses underscore and websocket in the offending file; I have overridden the require call for the module using imports-loader and injected underscore via the ProvidePlugin. This is the relevant portion of webpack config:
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.ProvidePlugin({
'_': 'underscore'
})
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['imports', 'react-hot', 'babel'],
include: path.join(__dirname, 'src')
}]
}
And I load the module as follows:
var Rserve = require ('imports?require=>(function(x){return(x==="ws"?global.WebSocket:_);})!rserve');
I sincerely hope there's a better way

I've found a better solution by aliasing ws in webpack and making a shim that simply returns WebSocket. Relevant portion of webpack.config:
resolve: {
alias: {
ws: path.resolve ('./') + '/src/shim/ws.js'
}
}
and in src/shim/ws.js:
module.exports = WebSocket || MozWebSocket;

Related

Webpack and SASS sourcemaps paths issue

I've make a very simple project to ilustrate the problem.
The project structure is:
The contents of webpack.config.js:
var path = require('path');
module.exports = {
entry: [
'./src/main.js',
'./src/main.scss'
],
output: {
path: path.join(__dirname, 'www/'),
filename: 'bundle.js'
},
module: {
loaders: [{
loaders: ['style-loader', 'css-loader?sourceMap', 'sass-loader?sourceMap'],
test: /\.scss$/
}]
},
devtool: 'source-map',
devServer: {
contentBase: 'www/'
}
};
The bundle generation is working properly, but when I debug the application, the SASS sourcemaps don't have the right base path:
Because it nests a second src/ folder in src/. I've tried to add to the sass-loader the sourceMapRoot option:
'sass-loader?sourceMap&sourceMapsRoot=src/'
But it doesn't fix the issue. I know it isn't significant, but I want to know if anyone have it working properly or have the same problem.
Best regards, thank you.

"transform-es3-member-expression-literals" usage in webpack 1.x

I am working on application that needs to be run on IE 8 enterprise version.I am getting following errors in the console:
Expected identifier : ;
indexOf is not available for the object.
For solving this I read this question on stackoverflow:
Babel 6.0.20 Modules feature not work in IE8
It suggests
transform-es3-member-expression-literals
transform-es3-property-literals
to be added.
But using this in webpack is not mentioned any where,not on babel official site.
Can anyone suggest the way how can I use it as a plugin to my project.
Note:I have already tried doing
var es3MemberExpressionLiterals = require('babel-plugin-transform-es3-member-expression-literals');
var es3PropertyLiterals = require('babel-plugin-transform-es3-property-literals');
plugins = [// Plugins for Webpack
new webpack.optimize.UglifyJsPlugin({minimize: false}),
new HtmlWebpackPlugin({
template: 'index.html', // Move the index.html file...
minify: { // Minifying it while it is parsed using the following, self–explanatory options
removeComments: false,
collapseWhitespace: false,
removeRedundantAttributes: false,
useShortDoctype: false,
removeEmptyAttributes: false,
removeStyleLinkTypeAttributes: false,
keepClosingSlash: true,
minifyJS: false,
minifyCSS: true,
minifyURLs: false
}
})
new es3MemberExpressionLiterals(),
new es3PropertyLiterals()
];
I've created a demo repository on github to show the full configuration by an example.
To get the two plugins running create a .babelrc file, with the following content
{
"plugins": [
"transform-es3-member-expression-literals",
"transform-es3-property-literals"
]
}
In the standard configuration babel-loader in your webpack.config.js babel takes a look into the .babelrc to configure plugins.
// webpack.config.js (partial code only)
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
}
If everything is set up correctly webpack should transform the following code
// src/main.js
var foo = { catch: function() {} };
console.log(foo.catch)
into
// bundle.js
/* 0 */
/***/ function(module, exports) {
var foo = { "catch": function () {} };
console.log(foo["catch"]);
/***/ }
See also the examples for the plugins: babel-plugin-transform-es3-property-literals and babel-plugin-transform-es3-member-expression-literals.
The question you link to is about Babel plugins, and you are trying to pass them as Webpack plugins. You'd need to set up Babel as a loader for your application and pass the plugins to that. Merge the following into your Webpack configuration.
module: {
loaders: [{
loader: 'babel',
test: /\.js$/,
exclude: /node_modules/,
plugins: [
'babel-plugin-transform-es3-member-expression-literals',
'babel-plugin-transform-es3-property-literals',
],
}],
},

Webpack, sass being overwriten

I'll start by saying I have a bit of a bizarre webpack build. I have 2 projects, the main project and the shared project (like a common library).
Whenever I refer to my shared project from the main project, it get some bizarre IE only/react/webpack build error where I get an error when trying to refer to my shared library. To solve this, I aliased my shared library references to the actual source on my computer in a different folder. That looks something like this:
var alias.shared-library = 'c:\\shared-library\\index.js';
This fixed my bizarre IE problem. However, another issue raised in my webpack production build. On the production server, the shared library exists within the node_modules folder, so I tried something like this:
var alias.shared-library = 'node_modules\\shared-library\\index.js';
It mostly works, except all my scss from the main project is overwritten by scss from the shared project (the output css only contains scss from the shared lib and not main). My full setup looks something like this (I removed parts I thought weren't important):
var SHARED_PATH = path.resolve(__dirname, 'node_modules/shared-library');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractCss = new ExtractTextPlugin('css.styles.css');
const extractScss = new ExtractTextPlugin('scss.styles.css');
const plugs = [];
plugs.push(
new webpack.DefinePlugin({
__DEVELOPMENT__: false
})
);
plugs.push(
new HtmlWebpackPlugin({
template: './index.html',
inject: 'body',
chunks: ['app', 'vendor']
})
);
plugs.push(new webpack.NoErrorsPlugin());
plugs.push(
new CopyWebpackPlugin([
{ from: 'src/assets', to: 'assets' },
])
);
plugs.push(
new SplitByPathPlugin([
{ name: 'vendor', path: [path.join(__dirname, 'node_modules')] },
])
);
plugs.push(extractCss);
plugs.push(extractScss);
plugs.push(
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
})
);
var alias = {
'shared-library': path.resolve(SHARED_PATH, '\\src\\index.js')
};
var loaderDirs = ['node_modules', 'webpack_loaders'];
var moduleDirs = ['node_modules', 'src'];
loaderDirs.push(SHARED_PATH + '\\node_modules');
moduleDirs.push(SHARED_PATH + '\\node_modules');
moduleDirs.push(SHARED_PATH + '\\src');
module.exports = {
entry: {
app: ['./src/index.js']
},
resolve: {
extensions: ['', '.js', '.scss', '.css'],
modulesDirectories: moduleDirs,
alias
},
resolveLoader: {
modulesDirectories: loaderDirs
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].[hash].js',
publicPath: '/main/',
sourceMapFilename: '[name].[hash].js.map',
chunkFilename: '[id].chunk.js',
},
plugins: plugs,
module: {
loaders: [
{
test: /\.js?$/,
loader: 'babel?sourceMaps=true',
include: [/src/, path.resolve(SHARED_PATH, '\\src\\index.js')]
},
{
test: /\.css$/,
loader: extractCss.extract('style', 'css')
},
{
test: /\.scss$/,
loader: extractScss.extract('style', 'css!sass'),
include: /src/ // Trying to exclude scss from shared-library, doesn't work though
},
loaders.json,
loaders.image,
loaders.svg,
loaders.font,
loaders.locale,
loaders.html
]
},
postcss: (webpack) => {
return [
autoprefixer({
browsers: ['last 2 versions'],
}),
postcssImport({
addDependencyTo: webpack,
})
];
},
externals: {
'react/lib/ReactContext': 'window',
'react/lib/ExecutionEnvironment': 'window',
'react/addons': true
}
};
I've tried things like different permutations of exclude/include on my loaders. I thought the allChunks option on ExtractTextPlugin might work:
const extractScss = new ExtractTextPlugin({filename: 'scss.styles.css', allChunks: true});
but it just gives me this error:
TypeError: path.replace is not a function
at Template.replacePathVariables (c:\r2\RCA\rca-ui\node_modules\webpack\lib\
TemplatedPathPlugin.js:70:4)
at Template.applyPlugins [as applyPluginsWaterfall] (c:\r2\RCA\rca-ui\node_m
odules\webpack\node_modules\tapable\lib\Tapable.js:37:47)
at Compilation.getPath (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilatio
n.js:882:27)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:300:29)
at Array.forEach (native)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:289:20)
at Compilation.next (c:\r2\RCA\rca-ui\node_modules\webpack\node_modules\tapa
ble\lib\Tapable.js:69:14)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:309:4)
at Compilation.applyPluginsAsync (c:\r2\RCA\rca-ui\node_modules\webpack\node
_modules\tapable\lib\Tapable.js:71:13)
at Compilation.<anonymous> (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compil
ation.js:563:8)
at Compilation.next (c:\r2\RCA\rca-ui\node_modules\webpack\node_modules\tapa
ble\lib\Tapable.js:67:11)
at ExtractTextPlugin.<anonymous> (c:\r2\RCA\rca-ui\node_modules\extract-text
-webpack-plugin\index.js:285:5)
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:52:16
at done (c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modu
les\async\lib\async.js:246:17)
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:44:16
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\index.js:269:6
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:52:16
at done (c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modu
les\async\lib\async.js:246:17)
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\node_modules\as
ync\lib\async.js:44:16
at c:\r2\RCA\rca-ui\node_modules\extract-text-webpack-plugin\index.js:259:9
at c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilation.js:469:4
at Array.forEach (native)
at callback (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilation.js:468:14
)
at Compilation.<anonymous> (c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compil
ation.js:489:4)
at c:\r2\RCA\rca-ui\node_modules\webpack\lib\Compilation.js:332:10
at c:\r2\RCA\rca-ui\node_modules\webpack\node_modules\async\lib\async.js:52:
16
at Object.async.forEachOf.async.eachOf (c:\r2\RCA\rca-ui\node_modules\webpac
k\node_modules\async\lib\async.js:236:30)
at Object.async.forEach.async.each (c:\r2\RCA\rca-ui\node_modules\webpack\no
de_modules\async\lib\async.js:209:22)
at Compilation.addModuleDependencies (c:\r2\RCA\rca-ui\node_modules\webpack\
lib\Compilation.js:185:8)
at Compilation.processModuleDependencies (c:\r2\RCA\rca-ui\node_modules\webp
ack\lib\Compilation.js:170:7)
Any ideas on the proper approach to solve this problem? Would the allChunks option help me here? Do I need to tighten up my include/excludes? Is there something else I'm missing? Should I give up and try and fix the IE problem another way? Is there a way I can debug what is happening? Here's the versions of the libraries I am using:
"extract-text-webpack-plugin": "1.0.1",
"style-loader": "0.13.0",
"sass-loader": "3.1.2",
"webpack": "1.13.2"
Thanks

Error when combining sass-loader with css-modules

I'm getting the following error when using SASS's map-get.
ERROR in ./src/special.scss
Module build failed: ModuleBuildError: Module build failed: Unknown word (11:14)
9 |
10 | #mixin mediaquery($name) {
> 11 | #media #{map-get($breakpoints, $name)} {
| ^
12 | #content;
13 | }
14 | }
This is only happening when I use both the sass-loader and another loader.
I first thought this was caused by the PostCSS Loader, but it seems like it's the sass-loading causing problems and not transforming the scss when using css-modules.
I've created a sample repo illustrating the problem: https://github.com/tiemevanveen/sass-css-components-fail-example.
You can use the different branches to test:
master: CSS Modules + SASS
postcss CSS Modules + SASS + PostCSS
log-source: Uses CSS modules + SASS + Custom source logging module
no-css-modules: SASS + Custom source logging module
Only the first and the last branch run without errors.
I've created the log-source example to see what the sass-loader is returning and it looks like it's not transforming the sass (but this might also be me misinterpreting how the loaders work).
The other example without css modules does show the right transformed code..
I'm puzzled why the master branch (without postcss or another custom loader) is working fine though.. if something would be wrong with the sass-loader then that one should also fail right?
I've filed an issue, but I'm thinking this has more chance on StackOverflow since it's such a specific problem and might be more a config problem. Here's my webpack config:
const webpack = require('webpack');
const path = require('path');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');
module.exports = {
devtool: 'source-source-map',
debug: true,
context: path.resolve(__dirname, './src'),
entry: {
app: './index.js'
},
output: {
path: path.resolve(__dirname, './static'),
filename: '[name].js',
publicPath: '/static/'
},
devServer: {
outputPath: path.resolve(__dirname, './static'),
},
plugins: [
new webpack.NoErrorsPlugin(),
new ExtractTextPlugin('[name].css'),
new WriteFilePlugin()
],
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', [
'css?modules&importLoaders=1&localIdentName=[path]_[name]_[local]',
// 'postcss-loader',
'sass'
])
},
// + js loader
]
},
postcss: [
autoprefixer({ browsers: ['> 0.5%'] })
],
resolveLoader: {
fallback: [
path.resolve(__dirname, 'loaders'),
path.join(process.cwd(), 'node_modules')
]
},
resolve: {
extensions: ['', '.js', '.json'],
}
};
You need to increase the importLoaders query parameter as you add loaders. That feature is poorly documented and confusing, but in your samples repo, importLoaders=2 with both Sass and PostCSS works.

jsx react debugger not matching despite webpack source maps

I'm learning React and JSX and using webpack to compile but when I throw in 'debugger' into my component, the line isn't matched when I'm in Chrome Dev Tools' Sources tab (in general the sources doesn't reflect what I have in my app.jsx file at all). The React tab doesn't really load up either. Below is my webpack.config:
module.exports = {
context: __dirname,
entry: "./api_assignment.jsx",
output: {
path: "./",
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react']
}
}
]
},
devtool: 'source-map',
resolve: {
extensions: ["", ".js", ".jsx"]
}
};
//Webpack screenshot
If you are loading your html from local file and not webpack server, you need to enable React Developer Tools extension option "Allow access to file URLs".

Resources