Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Uncaught SyntaxError: Unexpected token <" error happened sometimes #2882

Closed
ghost opened this issue Aug 17, 2016 · 22 comments
Closed

"Uncaught SyntaxError: Unexpected token <" error happened sometimes #2882

ghost opened this issue Aug 17, 2016 · 22 comments
Labels

Comments

@ghost
Copy link

@ghost ghost commented Aug 17, 2016

Currently I am working with webpack2 (beta-20) + React + express to create an universal web app. But when I build my script in development environment, sometimes I got an error

Uncaught SyntaxError: Unexpected token <

When I look into the file, it show the error occurs on

And this error will happened in both development and production. And when I remove all of the [hash] and [chunkhash], this error won't happened. I don't know why, does anyone has solution for this problem?

Here's my webpack.config.js :

const path = require('path');
const webpack = require('webpack');
const AssetsPlugin = require('assets-webpack-plugin');
const del = require('del');

const nodeEnv = process.env.NODE_ENV || 'development';
const isDev = nodeEnv !== 'production';

const rootPath = path.join(__dirname);
const srcPath = path.join(rootPath, './src');
const staticPath = path.join(rootPath, './static');
const cleanPath = [
  path.join(staticPath, './*'),
  path.join('!', staticPath, './favicon.ico'),
  path.join('!', staticPath, './assets.js'),
];

// The plug of cleaning static files, it used for production settings
class CleanPlugin {
  constructor(options) {
    this.options = options;
  }

  apply() {
    del.sync(this.options.files);
  }
}

// Setting the plugins for development and prodcution
function getPlugins() {
  const plugins = [];

  plugins.push(
    new webpack.DefinePlugin({
      'process.env': { NODE_ENV: JSON.stringify(nodeEnv) },
      __DEV__: JSON.stringify(isDev),
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: isDev ? '[name].[hash].js' : '[name].[chunkhash].js',
      minChunks: Infinity,
    }),
    new webpack.NoErrorsPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new AssetsPlugin({
      filename: 'assets.js',
      path: staticPath,
      processOutput: assets => `module.exports = ${JSON.stringify(assets)};`,
    })
  );

  if (isDev) {
    plugins.push(
      new webpack.HotModuleReplacementPlugin()
    );
  } else {
    plugins.push(
      new CleanPlugin({ files: cleanPath }),
      new webpack.LoaderOptionsPlugin({
        minimize: true,
        debug: false,
      }),
      new webpack.optimize.UglifyJsPlugin({
        compress: { screw_ie8: true, warnings: false },
        output: { comments: false },
        sourceMap: false,
      }),
      new webpack.optimize.DedupePlugin()
    );
  }

  return plugins;
}

// Webpack settings
module.exports = {
  cache: isDev,
  debug: isDev,
  devtool: isDev ? 'cheap-module-eval-source-map' : 'hidden-source-map',
  context: srcPath,
  entry: {
    app: isDev ? [
      'react-hot-loader/patch',
      'webpack-hot-middleware/client',
      './client.js',
    ] : './client.js',
    vendor: [
      'react', 'react-dom',
      'redux', 'react-redux',
      'redux-thunk',
      'react-router',
      'react-router-redux',
      'react-helmet',
      'axios',
    ],
  },
  output: {
    path: staticPath,
    publicPath: '/',
    filename: isDev ? '[name].[hash].js' : '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].js',
  },
  module: {
    preLoaders: [
      { test: /\.jsx?$/, loader: 'eslint', exclude: /node_modules/ },
    ],
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          cacheDirectory: isDev,
          babelrc: false,
          presets: [['es2015', { modules: false }], 'react', 'stage-0'],
          plugins: ['transform-runtime', 'react-hot-loader/babel'],
        },
      },
    ],
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.css', '.scss'],
    modules: [
      srcPath,
      'node_modules',
    ],
  },
  plugins: getPlugins(),
  eslint: { failOnError: true },
};

Here's my server.js :

import path from 'path';
import express from 'express';
import favicon from 'serve-favicon';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { Provider } from 'react-redux';
import { match, RouterContext } from 'react-router';
import routes from './routes';
import config from './config';
import configureStore from './configureStore';
import renderHtmlPage from './renderHtmlPage';

const app = express();

app.use(favicon(path.join(__dirname, '../static/favicon.ico')));
app.use('/static', express.static(path.join(__dirname, '../static')));

// Run express as webpack dev server
if (__DEV__) {
  const webpack = require('webpack');
  const webpackConfig = require('../webpack.config');

  const compiler = webpack(webpackConfig);

  app.use(require('webpack-dev-middleware')(compiler, {
    publicPath: webpackConfig.output.publicPath,
    noInfo: true,
    hot: true,
    stats: { colors: true },
  }));

  app.use(require('webpack-hot-middleware')(compiler));
}

// Render content
app.get('*', (req, res) => {
  match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
    if (error) {
      res.status(500).send(error.message);
    } else if (redirectLocation) {
      res.redirect(302, redirectLocation.pathname + redirectLocation.search);
    } else if (!renderProps) {
      res.sendStatus(404);
    } else {
      const store = configureStore();

      const promises = renderProps.components
        .filter(component => component.fetchData)
        .map(component => component.fetchData(store.dispatch, renderProps.params));

      Promise.all(promises)
        .then(() => {
          const content = renderToString(
            <Provider store={store}>
              <RouterContext {...renderProps} />
            </Provider>
          );
          const initialState = store.getState();

          res.status(200).send(renderHtmlPage(content, initialState));
        });
    }
  });
});

if (config.port) {
  app.listen(config.port, config.host, err => {
    if (err) console.error(`==> 😭  OMG!!! ${err}`);

    console.info(`==> 🌎  Listening at http://${config.host}:${config.port}`);
  });
} else {
  console.error('==> 😭  OMG!!! No PORT environment variable has been specified');
}

Here's my client.js :

import React from 'react';
import { render } from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { syncHistoryWithStore, routerReducer } from 'react-router-redux';
import configureStore from './configureStore';
import routes from './routes';

const initialState = window.__INITIAL_STATE__;
const store = configureStore(initialState, routerReducer);
const history = syncHistoryWithStore(browserHistory, store);

const renderApp = (CurrentAppRoutes: any) => {
  render(
    <AppContainer>
      <Provider store={store}>
        <Router history={history} routes={CurrentAppRoutes} />
      </Provider>
    </AppContainer>,
    document.getElementById('react-view')
  );
};

renderApp(routes);

// Enable hot reload by react-hot-loader
if (__DEV__) {
  if (module.hot) {
    module.hot.accept('./routes', () => {
      const NextAppRoutes = require('./routes').default;

      renderApp(NextAppRoutes);
    });
  }
}

Here's my renderHtmlPage.js :

import Helmet from 'react-helmet';
import assets from '../static/assets';

export default (content, initialState) => {
  const head = Helmet.rewind();

  // Setup html page
  return `
    <!DOCTYPE html>
    <html ${head.htmlAttributes.toString()}>
      <head>
        <meta char-set="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <meta http-equiv="Content-Language" content="en" />
        <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />

        ${head.base.toString()}
        ${head.title.toString()}
        ${head.meta.toString()}
        ${head.link.toString()}
      </head>
      <body>
        <div id="react-view">${content || null}</div>

        <script type="text/javascript">
          ${initialState && `window.__INITIAL_STATE__=${JSON.stringify(initialState)}`}
        </script>

        <!--[if gte IE 9 ]>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.9/es5-shim.min.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.9/es5-sham.min.js"></script>
        <![endif]-->

        ${assets && `<script src="${assets.vendor.js}"></script>`}
        ${assets && `<script src="${assets.app.js}"></script>`}
        ${head.script.toString()}
      </body>
    </html>
  `;
};

Here's the error message from Chrome :
2016-08-17 6 09 35

When this error happened, webpack usually occur build repeat :
2016-08-17 6 09 55

Error show on :
2016-08-17 10 45 55

@ghost ghost changed the title "Uncaught SyntaxError: Unexpected token <" happened in sometimes "Uncaught SyntaxError: Unexpected token <" happened sometimes not everytime Aug 17, 2016
@ghost ghost changed the title "Uncaught SyntaxError: Unexpected token <" happened sometimes not everytime "Uncaught SyntaxError: Unexpected token <" happened sometimes Aug 17, 2016
@ghost ghost changed the title "Uncaught SyntaxError: Unexpected token <" happened sometimes "Uncaught SyntaxError: Unexpected token <" error happened sometimes Aug 17, 2016
@JimmyDaddy
Copy link

@JimmyDaddy JimmyDaddy commented Aug 18, 2016

I have this problem too, did you get a solution?

@ghost
Copy link
Author

@ghost ghost commented Aug 18, 2016

@CJHJim,

Not yet, I am still trying to find the cause

@ghost
Copy link
Author

@ghost ghost commented Aug 18, 2016

Hi @CJHJim,

I have solved the error, I use webpack-isomorphic-tools instead of assets-webpack-plugin (It's a good tool, but I might don't know how to config it webpack-2), here's my updated webpack.config :

/* eslint max-len:0 */

const path = require('path');
const webpack = require('webpack');

const nodeEnv = process.env.NODE_ENV || 'development';
const isDev = nodeEnv !== 'production';

const WebpackIsomorphicToolsPlugin = require('webpack-isomorphic-tools/plugin');
const webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin(require('./webpackIsomorphicTools.config')).development(isDev);

const rootPath = path.join(__dirname, '..');
const srcPath = path.join(rootPath, './src');
const distPath = path.join(rootPath, './public/dist');

// Setting the plugins for development and prodcution
function getPlugins() {
  const plugins = [];

  plugins.push(
    new webpack.DefinePlugin({
      'process.env': { NODE_ENV: JSON.stringify(nodeEnv) },
      __DEV__: JSON.stringify(isDev),
    }),
    /* new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: isDev ? '[name].[hash].js' : '[name].[chunkhash].js',
      minChunks: Infinity,
    }), */
    new webpack.NoErrorsPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    webpackIsomorphicToolsPlugin
  );

  if (isDev) {
    plugins.push(
      new webpack.HotModuleReplacementPlugin()
    );
  } else {
    plugins.push(
      new webpack.LoaderOptionsPlugin({
        minimize: true,
        debug: false,
      }),
      new webpack.optimize.UglifyJsPlugin({
        compress: { screw_ie8: true, warnings: false },
        output: { comments: false },
        sourceMap: false,
      }),
      new webpack.optimize.DedupePlugin()
    );
  }

  return plugins;
}

// Webpack settings
module.exports = {
  cache: isDev,
  debug: isDev,
  devtool: isDev ? 'cheap-module-eval-source-map' : 'hidden-source-map',
  context: srcPath,
  entry: {
    main: isDev ? [
      'webpack-hot-middleware/client',
      'react-hot-loader/patch',
      './client.js',
    ] : './client.js',
    /* vendor: [
      'react', 'react-dom',
      'redux', 'react-redux',
      'redux-thunk',
      'react-router',
      'react-router-redux',
      'react-helmet',
      'axios',
    ], */
  },
  output: {
    path: distPath,
    publicPath: '/dist/',
    filename: isDev ? '[name].[hash].js' : '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].js',
  },
  module: {
    preLoaders: [
      { test: /\.jsx?$/, loader: 'eslint', exclude: /node_modules/ },
    ],
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          cacheDirectory: isDev,
          babelrc: false,
          presets: [['es2015', { modules: false }], 'react', 'stage-0'],
          plugins: ['transform-runtime', 'react-hot-loader/babel'],
        },
      },
    ],
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.css', '.scss'],
    modules: [
      srcPath,
      'node_modules',
    ],
  },
  plugins: getPlugins(),
  eslint: { failOnError: true },
};

@ghost ghost closed this Aug 18, 2016
@ryanlewis
Copy link

@ryanlewis ryanlewis commented Aug 18, 2016

@wellyshen what changes did you make to resolve your problem?

@ghost
Copy link
Author

@ghost ghost commented Aug 18, 2016

@ryanlewis I change the universal manifest plugin from assets-webpack-plugin to webpack-isomorphic-tools, I think my problem is I don't know how to set the assets-webpack-plugin with webpack-2 properly.

@JimmyDaddy
Copy link

@JimmyDaddy JimmyDaddy commented Aug 19, 2016

@wellyshen I found this is a "404" problem, the Router needed a javaScript file named '1.app.js' but got a html file, I checked this html file and found that's my default '404' error page.

@ghost
Copy link
Author

@ghost ghost commented Aug 19, 2016

@CJHJim It seems your router doesn't find the file from http request, so it return your error page back, if you are using react-router, I suggest you to get realize how it works.

@JimmyDaddy
Copy link

@JimmyDaddy JimmyDaddy commented Aug 19, 2016

@wellyshen I known the point, it just happened on the builded files, if I run it on development it works.
I think there was something wrong on my webpack's config.....

@ghost
Copy link
Author

@ghost ghost commented Aug 19, 2016

@CJHJim Did you use hash or chunkhash on production environment? If you did, you need webpack-isomorphic-tools to handle it or your html file can't access the bundled js file.

@hemedani
Copy link

@hemedani hemedani commented Feb 19, 2017

I have a same problem fix with
added <base href="/" /> into the <head> of my index.html

@Hideer
Copy link

@Hideer Hideer commented Mar 20, 2018

@hemedani same problem too, How to do??

@xemasiv
Copy link

@xemasiv xemasiv commented May 17, 2018

@hemedani May you please elaborate on why and how it works?
Did it for me, asking out of curiosity. Thank you.

@hemedani
Copy link

@hemedani hemedani commented May 19, 2018

It's because html 5 routing ...
search for it

@jandiralceu
Copy link

@jandiralceu jandiralceu commented Oct 11, 2018

@hemedani many many many thanks, dude! It solves my trouble!!!

@SalmanCse
Copy link

@SalmanCse SalmanCse commented Feb 5, 2019

,,,,,,,such type add but not solve @hemedani pls help error : ^ SyntaxError: Unexpected token <

@jayalakshmis
Copy link

@jayalakshmis jayalakshmis commented Feb 14, 2019

I have a same problem fix with
added <base href="/" /> into the <head> of my index.html

@hemedani How do i do this using webpack? Is there a plugin to insert the base tag?

@dark-swordsman
Copy link

@dark-swordsman dark-swordsman commented Apr 11, 2019

I am currently having this issue. I tried the base tag and the output: { publicPath: '/' } and they both aren't working.

@khanhpn
Copy link

@khanhpn khanhpn commented May 8, 2019

@hemedani unbelievable, after i added this line, and it worked as well.

@dev117uday
Copy link

@dev117uday dev117uday commented Apr 6, 2020

@dark-swordsman same problem, both solution not working for me

@vitorventurin
Copy link

@vitorventurin vitorventurin commented Nov 4, 2020

I have a same problem fix with
added <base href="/" /> into the <head> of my index.html

It worked but then I had one pitfall: when the web-app is "installed" on the device, once you open the app, it returns blank page instead of index page.

@rikoz
Copy link

@rikoz rikoz commented Dec 7, 2020

I have a same problem fix with
added <base href="/" /> into the <head> of my index.html

Please I am not using webpack, just a simple express setup. how do I fix this?

const express = require('express');
const path = require('path');
const ejs = require('ejs');
const open = require('open');

const app = express();
const port = 4050
// var router = express.Router()

app.engine('html', ejs.renderFile);

app.get('*', function (req, res) {
  res.sendFile(path.join(__dirname + '/index.html'))
})

app.use('/static', express.static(path.join(__dirname, '/assets')));

app.listen(port, (err) => {
  if (err) {
    console.log(err);
  } else {
    console.log(`listening on port ${port}!`)
    open(`http://localhost:${port}`);
  }
});

@mgdeveloper79
Copy link

@mgdeveloper79 mgdeveloper79 commented Aug 4, 2021

I am posting this in a hope help others incase if they reach this far and still have not found a fix. So along with many other issues, one possibility is if you are using html-webpack-plugin, you may find my answer useful.
webpack/webpack-dev-middleware#205

minsoftk added a commit to minsoftk/develog that referenced this issue Jan 15, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet