Uncaught SyntaxError:` Unexpected token import - javascript

I am working on a react application. Where I am using webpack and babel loader.
In my react application I am using import statement many times which is working fine.
Now I have My another stand alone application which is working fine.
Now I am installing my standalone application in react application using npm. So I do
let standAloneApplication = require("my_stand_alone_application")
But I get import error inside the standAloneApplication. Where I have a line
import controller from "./controller" // Main.js:1Uncaught SyntaxError: Unexpected token import
where as import statement in React application works fine. also the stand alone application work fine at alone. but together It's giving SyntaxError
my webpack file
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'html');
var APP_DIR = path.resolve(__dirname, 'html');
var config = {
entry: APP_DIR + '/app.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
devtool: "source-map",
node: {
fs: "empty"
} ,
module : {
loaders : [
{
test : /\.js?/,
include : APP_DIR,
exclude: /node_modules/,
loaders: ['babel?presets[]=react,presets[]=es2015,plugins[]=transform-decorators-legacy,plugins[]=transform-class-properties,plugins[]=transform-export-extensions'],
},
{ test: /\.json$/, loader: "json" }
]
}
}
module.exports = config;
main.js Code from stand alone application
import {Controller} from "./Controller/index.js"
export class Main () {
}

Notice the exclude: /node_modules/ in your loader setup.
Since you installed your app/module using npm, it's located in that directory, and because of the exclusion it will not be transpiled by Babel.
Perhaps, but I'm not sure, you can add it explicitly to the include line:
include : [
APP_DIR,
path.resolve(__dirname, 'node_modules/my_stand_alone_application')
]

Related

Module parse failed: Unexpected token (9:37) with babel-loader

I am serving the app through Express, which needs to use ES modules. Node does allow that, but I had to replace __dirname with another solution:
server.mjs:
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
This resulted in error with Babel, which required me to add extra plugin (https://babeljs.io/docs/en/next/babel-plugin-syntax-import-meta.html). I replaced original CRA with custom webpack and created .babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react"],
"plugins": ["#babel/plugin-syntax-import-meta"]
}
webpack.config.js:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js", // entry point to the application = top react component,
output: {
path: path.resolve(__dirname, "build"), // path where the transformed index.js will be stored
filename: "index_bundle.js", //name of the transformed file
},
module: {
rules: [
{
test: /\.(js|mjs|jsx)$/, use: {
loader: 'babel-loader',
}
}, // what files will be loaded by what procedure
{test: /\.css$/, use: ['style-loader', 'css-loader']},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
]
},
mode: "development",
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html" // will take the template file and transform it to include the rest
}),
]
};
I am still runing into an error when trying to build the app. It seems that all other files are built successfully, but server.mjs is still returning an error:
ERROR in ./src/server/server.mjs 9:66
Module parse failed: Unexpected token (9:66)
File was processed with these loaders:
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| import getInitialPlayerStates from "../components/functions/initialStateFunctions.mjs";
|
> var __dirname = path.resolve(path.dirname(decodeURI(new URL(import.meta.url).pathname)));
|
| var port = process.env.PORT || 4001;
# ./src/App.js 49:0-48 119:14-27
# ./src/index.js
Other .mjs files are being build alright unless I include the line with import.meta in their code - than they fail too.
What is wrong? How can I overcome this problem?
"es-dirname" library solves the problem without using "import.meta".
https://www.npmjs.com/package/es-dirname

How to properly export an ES6 module function as a library for use in a node app?

Let's say that I have a node.js application, which does NOT go through my webpack bundling:
Node App
const Html = require('./build/ssr-bundle.js');
let result = Html.ssrbundle.render();
console.log(result);
Here is my ES6/JSX file, which is getting processed by webpack and I want to be able to access that render function in my node app (you guessed right, I am trying to SSR react stuff ;) )
src/Html.js -(webpack)-> build/ssr-bundle.js
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import CustomComponent from './custom-component.js';
module.exports = {
render : function () {
return ReactDOMServer.renderToString(<CustomComponent />);
} };
And here is my Webpack config
webpack.config.js
var path = require('path');
module.exports = {
entry: {
ssr: './src/Html.js',
//frontend: './src/frontend-Html.js'
},
output: {
path: path.resolve(__dirname, 'build'),
filename: 'ssr-bundle.js',
library: 'ssrbundle'
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['env','react'],
plugins: ["transform-es2015-destructuring", "transform-object-rest-spread"]
}
},
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
},
stats: {
colors: true
},
devtool: 'source-map'
};
Whatever I do, I cannot figure out how to properly use that exported variable "ssrbundle" and subsequently the render function. If I had my node app included in the bundle, everything would be all right, but this is not what I want to do.
As apokryfos suggested, I played around with the libraryTarget Webpack setting. You can find more info on using Webpack to author a library (what I was really trying to achieve) here:
https://webpack.js.org/guides/author-libraries/
and here are code examples:
https://github.com/kalcifer/webpack-library-example/blob/master/webpack.config.babel.js.
What did the trick for me, was to set the libraryTarget to "umd" , which is different than the "var" setting which is set by default and is suitable i.e. for including the script in an HTML file

Using webpack with require module on client side Javascript in NodeJS application

I'm trying to follow this tutorial for creating a redux form in my NodeJS application. I put the code in my client side Javascript file and tried to run my application but I got a "require is not defined error". I'm using webpack to compile my Javascript file, which this other post suggested, so I'm not sure how I would go about using the require module on the client side. Is there a step I'm missing in order to be able to use the require module?
These are the lines in my client.js file that are causing the error:
import React, { Component, PropTypes } from 'react'
import { reduxForm } from 'redux-form'
This is what I have in webpack.config.js file:
var webpack = require('webpack');
var path = require('path');
var nodeExternals = require('webpack-node-externals');
var React = require('react');
var redux = require('redux');
var BUILD_DIR = path.resolve(__dirname, 'public');
var APP_DIR = path.resolve(__dirname, 'app');
var config = {
entry: APP_DIR + '/client.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
target: 'node',
externals: [nodeExternals()],
module: {
loaders: [
{
test: /\.jsx?/,
include: APP_DIR,
loader: 'babel'
}
]
}
};
module.exports = config;

webpack val loader causing exceptions

I'm trying to dynamically include a .js file at webpack compile time.
I don't want to use a context to load environmental variables, because I don't these magic variables in my code.
What I'm trying to do is use the val loader to execute a module. There use an environment variable to decide what module to import. And export that module.
However, this is causing other loaders to throw errors.
Here's my dir layout
--base
--src
app.js
test.js
webpack.config.js
rawr.js
Here my webpack.config.js file
var path = require('path');
var webpack = require('webpack');
// var process = require('process');
var env = require(process.env.NODE_ENV || './devConf.js');
module.exports = {
// Specify logical root of the sourcecode
plugins: [
new webpack.DefinePlugin(env)
],
context: path.join(__dirname, '/src'),
entry: {
app: ['bootstrap.js'],
},
// Specify where to put the results
output: {
path: path.join(__dirname, '/dist'),
filename: 'build.js'
},
// Specify logical root of package imports so as to avoid relative path everywhere
resolve: {
root: path.join(__dirname, '/src'),
// What files we want to be able to import
extensions: ['', '.js', '.css', '.less'],
},
module: {
preLoaders: [
// Lint all js before compiling
/*{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader'
}*/
],
loaders: [
{
test: /\.js$/,
query: {
presets: ['es2015']
},
exclude: /node_modules/,
loader: 'babel'
},
{
test: /\.tpl\.html$/,
exclude: /node_modules/,
loader: 'ngtemplate?relativeTo=/src/!html'
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
},
{
test: /\.css$/,
loaders: ["style", "css"]
}
]
},
// Dev server settings
devServer: {
contentBase: path.join(__dirname, '/dist'),
noInfo: false,
hot: true
},
// ESLint config
eslint: {
configFile: path.join(__dirname, '.eslintrc')
}
};
My js files look like this
// app.js
let b = require('val!test.js');
// test.js
var process = require('process');
loadedModule = require(process.env.NODE_ENV) // NODE_ENV='./rawr.js'
export const myString = loadedModule
// rawr.js
module.exports.test = "hello world";
The exception I'm getting:
ERROR in ./src/app/app.js
Module parse failed: /home/smaug/Projects/angular-template/node_modules/babel-loader/index.js?{"presets":["es2015"]}!/home/smaug/Projects/angular-template/src/app/app.js Line 1: Unexpected identifier
You may need an appropriate loader to handle this file type.
| 'use strict';
|
| require('angular-animate');
# ./src/bootstrap.js 7:0-18
It has nothing to do with what I'm trying to do. But if I remove the require('val!...') statment, it goes away.
Any ideas?
UPDATE:
If I change the require statement to be
let b = require('val!./test.js');
I get the following error:
ERROR in ./~/val-loader!./src/app/test.js
Module build failed: Error: Final loader didn't return a Buffer or String
at DependenciesBlock.onModuleBuild (/home/smaug/Projects/angular-template/node_modules/webpack-core/lib/NormalModuleMixin.js:299:42)
at nextLoader (/home/smaug/Projects/angular-template/node_modules/webpack-core/lib/NormalModuleMixin.js:275:25)
at /home/smaug/Projects/angular-template/node_modules/webpack-core/lib/NormalModuleMixin.js:292:15
at runSyncOrAsync (/home/smaug/Projects/angular-template/node_modules/webpack-core/lib/NormalModuleMixin.js:160:12)
at nextLoader (/home/smaug/Projects/angular-template/node_modules/webpack-core/lib/NormalModuleMixin.js:290:3)
at /home/smaug/Projects/angular-template/node_modules/webpack-core/lib/NormalModuleMixin.js:292:15
at Object.context.callback (/home/smaug/Projects/angular-template/node_modules/webpack-core/lib/NormalModuleMixin.js:148:14)
at Object.module.exports (/home/
// app.js
let b = require('val!./test.js');
This is a very confusing Error Message..
Check for the following mishaps..
import statement is pointing to the exact file;
typo errors in the file name on import statement; importing the
modules which are not present.
check whether you have installed all
the loaders like
css-loader node-sass resolve-url-loader sass-loader\
style-loader url-loader
4.import statement is empty
ex:
import * from '';
5. Services and Providers returning nothing may also cause this error.
test.js is supposed to return a string that contains the code that is supposed to be given to the module that is requiring it. So, for your example, test.js should go from this
var process = require('process');
loadedModule = require(process.env.NODE_ENV) // NODE_ENV='./rawr.js'
export const myString = loadedModule
to this
var process = require('process')
loadedModule = require('raw-loader!' + process.env.NODE_ENV)
export const myString = loadedModule
Using the "raw-loader" you will get the text code from rawr.js rather than the value that rawr.js exports. "val-loader" will then give rawr.js's code to the require in app.js and it will load that text as if it was the text of the file that you were trying to load.
That was probably a terrible explanation, but just remember that when you use val-loader, you need to return a string containing code.

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