trouble importing components in react - javascript

Hi I'm having trouble importing components from one jsx into another. I'm using a django framework to serve my webfiles and I've downloaded all the necessary tools (npm, webpack, webpack-bundle-tracker, babel loader, django-webpack loader). Webpack does a good job taking all of the seperate javascript files and turning them into a bundle in which my local django server can then render. The issue lies in when I try to import a component from one jsx into another jsx. There aren't any errors that I see but the javascript that I'm trying to import doesn't load on django.
Example: File:index.js
var React = require('react')
var ReactDOM = require('react-dom')
var Body = require('./app.js')
ReactDOM.render(<Body message="Welcome to my website"/>, document.getElementById('app1'))
Import file (which is in the same directory as index.js): File:app.js
var React = require('react')
var Body = React.createClass({
getInitialState: function() {
return {
bodymessage: this.props.message
}
},
render: function() {
return (
<h1>
{this.state.bodymessage}
</h1>
)
}
})
module.exports = Body;
Is there something wrong with my configuration?
Here's my webpack.config.js file :
var path = require('path')
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
module.exports = {
context: __dirname,
entry: './assets/js/index',
output: {
path: path.resolve('./assets/bundles/'),
filename: '[name]-[hash].js',
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
],
module: {
loaders: [
{test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react']
}
}
]
},
resolve: {
modulesDirectories: ['node_modules', 'bower_components'],
extensions: ['', '.js', '.jsx']
}
}

Try replacing loader: 'babel-loader', with loader: 'babel', in your webpack config

Related

Webpack throws TypeError: Super expression must either be null or a function, not undefined when importing LESS file

I have the following in a file initialize.js:
import App from './components/App';
import './styles/application.less';
document.addEventListener('DOMContentLoaded', () => {
const app = new App();
app.start();
});
In webpack.config.js I have:
'use strict';
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const ProvidePlugin = webpack.ProvidePlugin;
const ModuleConcatenationPlugin = webpack.optimize.ModuleConcatenationPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const extractLess = new ExtractTextPlugin({
filename: 'app.css',
});
const webpackCommon = {
entry: {
app: ['./app/initialize']
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader?presets[]=es2015'
}]
}, {
test: /\.hbs$/,
use: {
loader: 'handlebars-loader'
}
}, {
test: /\.less$/,
exclude: /node_modules/,
use: extractLess.extract({
use: [{
loader: 'css-loader'
}, {
loader: 'less-loader'
}],
// use style-loader in development
fallback: 'style-loader'
}),
}]
},
output: {
filename: 'app.js',
path: path.join(__dirname, './public'),
publicPath: '/'
},
plugins: [
extractLess,
new CopyWebpackPlugin([{
from: './app/assets/index.html',
to: './index.html'
}]),
new ProvidePlugin({
$: 'jquery',
_: 'underscore'
}),
new ModuleConcatenationPlugin(),
],
};
module.exports = merge(webpackCommon, {
devtool: '#inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
compress: true,
port: 9000
}
});
I tried removing the the plugins and the contents of application.less, but I keep getting this error:
ERROR in ./node_modules/css-loader!./node_modules/less-loader/dist/cjs.js!./app/styles/application.less
Module build failed: TypeError: Super expression must either be null or a function, not undefined
at ...
# ./app/styles/application.less 4:14-127
# ./app/initialize.js
If I replace that LESS file with a CSS one and update the config it works fine, so I guess the problem has to do with less-loader.
I'm using Webpack 3.4.1, Style Loader 0.18.2, LESS Loader 4.0.5, Extract Text Webpack Plugin 3.0.0 and CSS Loader css-loader.
My bad, I didn't notice I was using an old less version. That was the culprit. Just updated it to 2.7.2 and the problem is gone.

how to install reactjs npm package correctly

Hi I want to install this reactjs package called react-dropdown-input
https://github.com/RacingTadpole/react-dropdown-input/
I ran this command
$npm install react-dropdown-input --save
in my local folder in git bash. After that I checked my package.json, it says "react-dropdown-input": "^0.1.11" which means i have installed it correctly.
Then i tried to use it in my js file
import React from 'react'
import PropTypes from 'prop-types';
var DocumentTitle = require('react-document-title');
//var DropdownInput = require('react-dropdown-input');
When i added the fifth line, my page just could not load anymore (a blank page)
I dont know how to fix this.
Here's my webpack.config.js
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const path = require('path');
const webpack = require('webpack');
const BaseFolder = 'static/'; //relative to html path
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractLess = new ExtractTextPlugin({
filename: '[name].[contenthash].css',
disable: process.env.NODE_ENV === 'development'
});
var loaders = ['babel-loader'];
var port = process.env.PORT || 3000;
var vendor = ['react', 'react-dom', 'react-router', 'whatwg-fetch', 'es6-promise'];
var outputDir = 'dist';
var entry = {
filename: path.resolve(__dirname, 'src/app.js'),
}
var plugins = [
new webpack.optimize.CommonsChunkPlugin({
name:'vendor',
minChunks: Infinity,
filename: BaseFolder + 'js/[name].js',
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, '/src/index.html'),
filename: 'index.html',
inject: 'body'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'BaseFolder': JSON.stringify(BaseFolder)
}),
//new webpack.optimize.LimitChunkCountPlugin({maxChunks: 1}),
extractLess,
new webpack.ProvidePlugin({
Promise: 'es6-promise',
fetch: 'imports-loader?this=>global!exports-loader?global.fetch!whatwg-fetch',
React: 'react',
jsSHA: 'jssha',
wx: 'weixin-js-sdk'
}),
new CopyWebpackPlugin([
{
from: 'src/images',
to: BaseFolder + 'images'
}
])
];
if (process.env.NODE_ENV === 'development') {
//devtool ='eval-source-map';
loaders = ['react-hot-loader'].concat(loaders);
plugins = plugins.concat([
new webpack.HotModuleReplacementPlugin()
]);
entry = Object.keys(entry).reduce(function (result, key) {
result[key] = [
'webpack-dev-server/client?http://0.0.0.0:' + port,
'webpack/hot/only-dev-server',
entry[key]
];
return result;
}, {});
}
entry.vendor = vendor;
module.exports = env => {
return {
entry: entry,
output: {
filename: BaseFolder+'js/bundle.js',
chunkFilename: BaseFolder+'js/[id].chunk.js',
path: path.resolve(__dirname, outputDir),
publicPath: '/'
},
externals: [
],
module: {
loaders: [
{
test: /.jsx?$/,
loader: loaders,
exclude: /node_modules/,
include: __dirname
},
{ test: /\.js$/, exclude: /node_modules/, loaders: loaders, include: __dirname},
{ test: /\.scss$/, exclude: /node_modules/, loader: 'style-loader!css-loader?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap&includePaths[]=node_modules/compass-mixins/lib'},
{ test: /\.css$/, loader: 'style-loader!css-loader', exclude: /\.useable\.css$/},
{
test: /\.useable\.css$/,
use: [
{
loader: 'style-loader/useable'
},
{ loader: 'css-loader' },
],
},
{ test: /\.(png|jpg|jpeg|gif)$/, loader: 'url-loader?limit=100000&name='+BaseFolder+'images/[name].[ext]' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?name='+BaseFolder+'fonts/[name].[ext]' },
{ test: /\.(woff|woff2)$/, loader:'url-loader?prefix=font/&limit=5000&name='+BaseFolder+'fonts/[name].[ext]' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream&name='+BaseFolder+'fonts/[name].[ext]' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml&name='+BaseFolder+'images/[name].[ext]' },
]
},
plugins: plugins
}
};
Yes this must be included in your node_modules, but the point is that you have include that in your compiled js file or not, i.e.
you must have used webpack or gulp to compile all your dependencies of js to give one file and you must have forget to include that dependency file in webpack file or gulpfile, Please check or provide sample of your webpack or gulpfile.
I think that DropdownInput is named export from react-dropdown-input since in index.js file in the repository its exported as
module.exports = DropdownInput;
So need to import it like
import {DropdownInput} from 'react-dropdown-input'

Correctly bundled image could not be loaded

I have a very simple React component, that is supposed to display an image.
I am also using Webpack for bundling.
It's probably worth noting that I am using ReactJS.NET.
Although the webpack bundle builds properly, and the .jpg generated by webpack is viewable (using Windows Photo Viewer, for example), the image does not display in my View.
When I take a peek into inspector, the html structure is built properly, but I am getting:
"Could not load the image" - when I hover over the image path.
I made sure that the image path is correct.
Below is my react component:
var React = require('react');
var BackgroundImg = require('./Images/img_fjords.jpg');
class Login extends React.Component {
render() {
return (
<img src={BackgroundImg} />
);
}
componentDidMount() {
console.log("Mounted");
}
}
module.exports = Login;
Webpack config:
var path = require('path');
var WebpackNotifierPlugin = require('webpack-notifier');
module.exports = {
context: path.join(__dirname, 'App'),
entry: {
server: './server',
client: './client'
},
output: {
path: path.join(__dirname, 'Built/'),
publicPath: path.join(__dirname, 'Built/'),
filename: '[name].bundle.js'
},
plugins: [
new WebpackNotifierPlugin()
],
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff"
},
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" },
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' },
{ test: /\.jsx$/, loader: 'jsx-loader?harmony' }
]
},
resolve: {
// Allow require('./blah') to require blah.jsx
extensions: ['.js', '.jsx']
},
externals: {
// Use external version of React (from CDN for client-side, or
// bundled with ReactJS.NET for server-side)
react: 'React'
}
};
The problem was solved thanks to help from #Luggage.
The webpack.config was wrong, it should have been:
output: {
path: path.join(__dirname, 'Built/'),
publicPath: 'Built/',
filename: '[name].bundle.js'
},
Well, I can't see your webpack config, but I'm assuming your using all the correct loaders (file-loader, extract-loader, html-loader, url-loader)? The way I handle it is using the webpack-copy-plugin to copy over my images folder so relative paths still work.

Import Javascript library globally via Webpack

I am trying to remove script tags for javascript libraries from my html, and so have removed underscore.js from a template page.
To replace this, within my index.js (webpack entry point), I have the following
import 'underscore';
The size of the webpack outputted bundle.js file increases by 50k when I do this, so I know that the library is in bundle.js. However, underscore is not available when I try to use it in the console on a page which has the bundle.js included.
Any thoughts would be appreciated.
const webpack = require('webpack');
const path = require('path');
const precss = require('precss');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const postcssImport = require('postcss-import');
module.exports = {
context: __dirname + '/frontend',
devtool: 'source-map',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, './static'),
},
module: {
loaders: [
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/, query: { presets: ['es2015'] } },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap&importLoaders=1!postcss') },
],
},
vendor: [
'underscore',
],
plugins: [
new ExtractTextPlugin('si-styles.css'),
new webpack.ProvidePlugin({
underscore: 'underscore',
}),
],
postcss: function(webpack) {
return [
postcssImport({ addDependencyTo: webpack }), // Must be first item in list
precss,
autoprefixer({ browsers: ['last 2 versions'] }),
];
},
};
In order to achieve that you can use this webpack plugin:
new webpack.ProvidePlugin({
underscore: "underscore"
})
by the way it is not necessary that you import the library in the index file of your directory. You will have access to the library also specifying a new entry point in your webpack config file.. You could then put all your vendor code in a vendor.js boundle like so:
entry: {
main: [
'./app/js/main.js'
],
vendor: [
'underscore',
'lodash',
'my-awesome-library!'
]
}
UPDATE: There is a very good tutorial in how to use webpack in production on egghead.io.. Try to check it out!

What is the best practice for importing angularjs using webpack?

How do you use Webpack and AngularJS together, and how about template loading and on demand fetching of resources?
An example of a well written webpack.config.js file for this purpose would be very much appreciated.
All code snippets displayed here can be accessed at this github repo. Code has been generously adapted from this packetloop git repo.
webpack.config.json
var path = require('path');
var ResolverPlugin = require("webpack/lib/ResolverPlugin");
var config = {
context: __dirname,
entry: ['webpack/hot/dev-server', './app/app.js'],
output: {
path: './build',
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.css$/,
loader: "style!css-loader"
}, {
test: /\.scss$/,
loader: "style!css!sass?outputStyle=expanded"
}, {
test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$/,
loader: "file"
}, {
test: /\.html$/,
loader: "ngtemplate?relativeTo=" + path.join(__dirname, 'app/') + "!raw"
}]
},
// Let webpack know where the module folders are for bower and node_modules
// This lets you write things like - require('bower/<plugin>') anywhere in your code base
resolve: {
modulesDirectories: ['node_modules', 'lib/bower_components'],
alias: {
'npm': __dirname + '/node_modules',
'vendor': __dirname + '/app/vendor/',
'bower': __dirname + '/lib/bower_components'
}
},
plugins: [
// This is to help webpack know that it has to load the js file in bower.json#main
new ResolverPlugin(
new ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
]
};
module.exports = config;
To import AngularJS into the main app.js you do the following:
app/vendor/angular.js
'use strict';
if (!global.window.angular) {
require('bower/angular/angular');
}
var angular = global.window.angular;
module.exports = angular;
And then use it in app.js like so,
app.js
...
var angular = require('vendor/angular');
// Declare app level module
var app = angular.module('myApp', []);
...
Is the following correct? Is there an easier way to do this? I've seen a few (not a lot by any standards) posts which listed another method.
From this reddit post comment
// Add to webpack.config.js#module#loaders array
{
test: /[\/]angular\.js$/,
loader: "exports?angular"
}
There is also another plugin which is in development right now, at stackfull/angular-seed. It seems to be in the right direction, but is really really hard to use right now.
Webpack is way awesome, but the lack of documentation and samples are killing it.
You can just require angular in all modules (files) where you need it. I have a github repository with example how to do that (also using webpack for build). In the example ES6 import syntax is used but it shouldnt matter, you can use standard require() instead.
Example:
import 'bootstrap/dist/css/bootstrap.min.css';
import './app.css';
import bootstrap from 'bootstrap';
import angular from 'angular';
import uirouter from 'angular-ui-router';
import { routing} from './app.config';
import common from './common/common.module';
import featureA from './feature-a/feature-a.module';
import featureB from './feature-b/feature-b.module';
const app = angular
.module('app', [uirouter, common, featureA, featureB])
.config(routing);
I am starting with Angular + Flux with Webpack so may be I can help you with some things.
Basically I am installing everything with NPM, it has module export system, so it works like nothing. (You can use export-loader, but why if you do not need to.)
My webpack.config.js looks like this:
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require("html-webpack-plugin");
var nodeModulesDir = path.resolve(__dirname, './node_modules');
// Some of my dependencies that I want
// to skip from building in DEV environment
var deps = [
'angular/angular.min.js',
...
];
var config = {
context: path.resolve(__dirname, './app'),
entry: ['webpack/hot/dev-server', './main.js'],
resolve: {
alias: {}
},
output: {
path: path.resolve(__dirname, './build'),
filename: 'bundle.js'
},
// This one I am using to define test dependencies
// directly in the modules
plugins: [
new webpack.DefinePlugin({
ON_TEST: process.env.NODE_ENV === 'test'
})
],
module: {
preLoaders: [
{test: /\.coffee$/, loader: "coffeelint", exclude: [nodeModulesDir]}
],
loaders: [
{test: /\.js$/, loader: 'ng-annotate', exclude: [nodeModulesDir]},
{test: /\.coffee$/, loader: 'coffee', exclude: [nodeModulesDir]},
...
],
noParse: []
},
devtool: 'source-map'
};
if (process.env.NODE_ENV === 'production') {
config.entry = {
app: path.resolve(__dirname, './app/main.js'),
vendors: ['angular']
};
// config.output.path = path.resolve(__dirname, './dist');
config.output = {
path: path.resolve(__dirname, "./dist"),
filename: "app.[hash].js",
hash: true
};
config.plugins.push(new webpack.optimize.UglifyJsPlugin());
config.plugins.push(new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.[hash].js'));
config.plugins.push(new HtmlWebpackPlugin({
title: 'myApp',
template: path.resolve(__dirname, './app/index.html'),
inject: 'body'
}));
delete config.devtool;
}
else {
deps.forEach(function (dep) {
var depPath = path.resolve(nodeModulesDir, dep);
config.resolve.alias[dep.split(path.sep)[0]] = depPath;
config.module.noParse.push(depPath);
});
}
module.exports = config;
My main.js looks like this:
var angular = require('angular');
if(ON_TEST) {
require('angular-mocks/angular-mocks');
}
require('./index.coffee');
And index.coffee containt main angular module:
ngModule = angular.module 'myApp', []
require('./directive/example.coffee')(ngModule)

Categories