Spread operator not working in Object.assign() - ecmascript-6

I'm trying to use the spread operator to populate a new object from an old object, without copying the pointer of the old object. But the new object comes out empty. :(
Here's my code:
const obj = {
a: 'a',
b: 'b',
c: 'c'
};
const test1 = Object.assign({}, ...obj);
const test2 = {};
console.log('obj', obj);
console.log('test1', test1);
console.log('test2', test2);
test1 should show up in the console with the same content as obj, but it's empty.
What am I doing wrong? Is there another way of doing it, without using Object.assign()?
(Also have this in a jsbin.)
UPDATE:
I've tried:
const test = {...obj};
But I keep getting Unexpected token on the first dot of the spread. It works in JSBin, but not on my local. So I'm thinking I may have done something wonky with Webpack or Babel.
Here's my webpack.config.js:
var path = require('path');
const DEV = process.env.NODE_ENV === 'dev';
const PROD = process.env.NODE_ENV === 'prod';
module.exports = {
devtool: 'source-map',
entry: './src/index.js',
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel-loader'],
exclude: /node_modules/
},{
test: /\.(png|jpg|gif)$/,
loaders: ['url-loader'],
exclude: /node_modules/
},{
test: /\.(css|sass|scss)$/,
use: ['style-loader', 'css-loader?importLoaders=2', 'sass-loader'],
// exclude: /node_modules/
},{
test: /\.(svg)$/,
use: ['file-loader'],
// exclude: /node_modules/
},
{
test: /\.(otf)(\?.*)?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-sfnt'
}]
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/dist/',
filename: 'bundle.js'
}
}
And here's my .babelrc:
{
"presets": ["env", "react"]
}

When you spread an object you need to wrap it inside an object body (same goes for arrays):
const test1 = Object.assign({}, {...obj});
With that said, i don't see any benefit from combine Object.assign with the object spread.
You could just do:
const test1 = {...obj};
Or this:
const test1 = Object.assign({}, obj);
Edit
I should mention that the object spread syntax is a proposal (in stage 3) and you need the babel plugin babel-plugin-transform-object-rest-spread to support it.
Just do:
npm install --save-dev babel-plugin-transform-object-rest-spread
And add it in your .babelrc file:
{
"plugins": ["transform-object-rest-spread"]
}

The spread operator is not properly used in this case.
You just want: Object.assign({}, obj), alternatively: test1 = { ...obj }. What you are doing is more like Object.assign({}, obj.a, obj.b, obj.c);

Related

Adding additional module export from external file to webpack bundle

I have a project that requires an additional "config" file that I would like compiled into the final webpack bundle as an additional export of the bundled library.
The condition is that this config file, shouldn't need to be added to the entry file, but simply added an an additional export to the bundle.
I'm still relatively new to Webpack, but have been looking into how I might be able to accomplish this for a while now with no avail. Any help on getting into the right direction would be greatly appreciated!
Entry File (ts, using ts-loader):
export default class TestPlugin {
this.name: string;
constructor(name: string) {
this.name = name;
}
}
Plugin "config".
{
"name": "test plugin"
}
Plugin "loader" logic (separate project).
const plugin = require(path.resolve(pluginDirectory, fileName)
const config = plugin.config
const newPlugin = new plugin(config.name)
Webpack Config.
entry: ['./src/index.ts'],
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
output: {
filename: 'example.plugin.js',
path: path.resolve(__dirname, 'build'),
library: 'plugin',
libraryTarget: 'umd',
libraryExport: 'default',
globalObject: 'this',
},

Webpack replace asset for cache busting

I have question, might be really silly as I am a beginner with Webpack but so far impressed.
So, I have a really small personal project with Flask(Python) on the backend and React on the frontend and I'm fighting with cache busting (I mean, not now, while I'm developing no problem whatsoever with cache, but I'm worrying already for when I deploy).
I am using Webpack to bundle the js and css (right now just the js though). So I was wondering if it is possible with Webpack for me to write, say in the css, something like:
some-selector {
background: #00ff00 url("my-background.png") no-repeat fixed center;
}
or in the HTML
<script src="bundle.js"></script>
and have Webpack to replace those strings with the resource with a cache busting hash for when building for production?
like
some-selector {
background: #00ff00 url("my-background.987asdh23193jf13.png") no-repeat fixed center;
}
and
<script src="bundle.23kjbi24f92do20f.js"></script>
I saw some sutff about html-webpack-plugin or string-replace-loader but not quite what I was looking for.
So, the questions:
is it possible with Webpack?
is it possible at all?
is there a better way to do it?
Yes it is possible to do cache busting using webpack and you can use this code for that or reference is https://medium.com/#okonetchnikov/long-term-caching-of-static-assets-with-webpack-1ecb139adb95#.nctflpxl2
I never tried for images but it is also possible using webpack.
var webpack = require('webpack');
const path = require("path");
var ChunkHashReplacePlugin = require('chunkhash-replace-webpack-plugin');
var WebpackMd5Hash = require('webpack-md5-hash');
var ManifestPlugin = require('webpack-manifest-plugin');
var node_dir = __dirname + '/node_modules';
var HtmlWebpackPlugin = require('html-webpack-plugin');
var InlineManifestWebpackPlugin=require('inline-manifest-webpack-plugin');
module.exports = {
context: __dirname + '/app',
entry: {
app: './app.js',
vendor: ['angular', 'underscore', 'restangular', 'angular-ui-router', 'bootstrap', 'angular-ui-bootstrap', 'angular-animate', 'angular-sanitize']
},
output: {
path: path.join(__dirname, "js"),
filename: "[name].bundle.js"
// filename: "[name].[chunkhash].bundle.js"
},
plugins: [
function() {
this.plugin("done", function(stats) {
require("fs").writeFileSync(
path.join(__dirname, "js", "stats.json"),
JSON.stringify(stats.toJson()));
});
},
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.ProvidePlugin({
_: "underscore",
underscore: "underscore"
}),
new webpack.optimize.CommonsChunkPlugin({
name: ["vendor"], // vendor libs + extracted manifest
minChunks: Infinity
}),
new ManifestPlugin({
filename: "chunk-manifest.json",
manifestVariable: "webpackManifest"
}),
new WebpackMd5Hash(),
new InlineManifestWebpackPlugin({
name: 'webpackManifest'
}),
new HtmlWebpackPlugin({
title: ' Portal',
template: 'index.ejs',
filename:'../index.html'
})
],
devServer: {
inline: true,
headers: { "Access-Control-Allow-Origin": "*" }
},
resolve: {
alias: {
"underscore": node_dir + "/underscore/underscore-min.js"
}
}
};
};

Trying to use request with ES6 + Webpack, but I am getting an error

I am currently trying to create a webapp with React, and I am trying to make a request to my server (with request). However, whenever I try to webpack the app I get an error. I am almost certain it has to do with request having to be labeled as an external library, but I can't get it to work. Can anybody help me?
Here is my webpack config.
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCSS = new ExtractTextPlugin();
module.exports = {
entry : [
'./js/index.js'
],
output : {
path : __dirname + '/lib/',
publicPath : 'http://localhost:8080',
filename : 'bundle.js'
},
plugins : [
new ExtractTextPlugin('app.css'),
new webpack.NoErrorsPlugin()
],
module : {
loaders : [
{
test : /\.js$/,
loaders : [
'babel'
],
exclude : /node_modules/
},
{
test : /\.(jpe?g|png|gif|svg)$/i,
loaders : [
'url?limit=8192',
'img'
]
},
{
test : /\.scss$/,
include : /styles/,
loader : extractCSS.extract([
'css',
'autoprefixer',
'sass'
])
}
]
},
resolve : {
extensions : ['', '.js', '.json']
},
externals : {
request : 'request'
}
};
and here is the error that I am getting
ERROR in ./js/services/comic
Module parse failed: /Users/matthew.pfister/IdeaProjects/web/js/services/comic Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import request from 'request';
|
| export default {
# ./js/creators/comic.js 11:21-49
Here is the file it is referencing
import request from 'request';
export default {
...
};
I dont think export default {...} is valid. try
var o = {...}
export default o
should work.
I just realized that the file that is throwing the error doesn't have the .js extension.
::facepalm:: everything is fixed.

Exposing a Javascript object as a module in webpack

Inside webpack.config.js I have computed a javascript map that I'd like import as a module in the browser. I could write the data to disk and then read it back with e.g https://github.com/webpack/json-loader, but is there any more elegant ways to do this in-memory?
webpack.config:
var config = {
key: 'data'
}
// do something with webpack loaders
some.file.that.is.executed.in.browser.js:
var config = require('config')
window.alert('Config is', config.key)
webpack loaders are file preprocessor, thus there needs to be the file that you import. So create a dummy file and use json-string-loader to override the contents.
Create an empty config.json to your project.
In webpack.config.js:
var appConfig = {
key: 'data'
}
...
loaders: [
{
test: /config.json$/,
loader: 'json-string-loader?json=' + JSON.stringify(appConfig)
}
In browser:
var appConfig = require("./config.json");
// => returns {key: 'data'}
I could write the data to disk and then read it back with e.g
https://github.com/webpack/json-loader, but is there any more elegant
ways to do this in-memory?
Why? You can just do whatever you need in config.js (instead of static json) and just return a result:
var data = 'foo' + 'bar';
module.exports = {
key: data
}

Using gruntjs, how would I get data from "nested" json files?

Let's say in my Gruntfile I have pkg: grunt.file.readJSON('package.json'), and inside the package.json is the following object:
{
"file": "data.json"
}
How would I access the data from data.json? Which might look something like this:
{
"name": "Jon Schlinkert",
"company": "Sellside"
}
Just load the first file, then use the result of that to load the second file and add it to the grunt config. Like this:
module.exports = function (grunt) {
var pkg = grunt.file.readJSON('package.json');
grunt.initConfig({
pkg: pkg,
data: grunt.file.readJSON(pkg.file),
task: {
target: {
files: {
'dest': '<%- data.name %>'
}
}
}
});
grunt.registerMultiTask('task', function() {});
console.log('name', grunt.config('data.name'));
};
Maybe I don't understand the problem, but what about:
var pkg = grunt.file.readJSON('package.json');
var data = grunt.file.readJSON(pkg.file);