Angular - Unexpected token <

11,995

Solution 1

I think the issue is that your script files are loaded from the root level making your browser request http://example.com/XXX.js. That's why they fall in the Express' * route. This means every request for XXX.js gets the same index.html file which can't be properly parsed by JS engine.

Solution 2

Like Mateusz said - all of your requests are returning the index.html file. If you open up the developer tools in Chrome and look under the "Network" tab and view the responses for each of those files you'll see the contents of each of those files is actually the index.html file. What you need to do is make an list of exceptions to allow the server to return those js files and other file types like images.

const allowed = [
  '.js',
  '.css',
  '.png',
  '.jpg'
];

// Catch all other routes and return the angular index file
app.get('*', (req, res) => {
   if (allowed.filter(ext => req.url.indexOf(ext) > 0).length > 0) {
      res.sendFile(path.resolve(`client/dist/cient/${req.url}`));
   } else {
      res.sendFile(path.join(__dirname, 'client/dist/client/index.html'));
   }
});
Share:
11,995
Milad ABC
Author by

Milad ABC

Self-motivated Software Engineer with 2+ years of experience in developing robust backend web services. Interested in designing and implementing distributed systems and microservice architecture. Detail-oriented with problem solving skills in efficient and reasonable time. Extremely motivated to constantly develop my skills and grow professionally.

Updated on August 10, 2022

Comments

  • Milad ABC
    Milad ABC over 1 year

    I have set up an angular and express app with angular-cli and express command lines respectively. I've already build angular app with ng build and when I want to serve it with express server I get following error in google chrome console:

    Uncaught SyntaxError: Unexpected token <    runtime.js:1
    Uncaught SyntaxError: Unexpected token <    polyfills.js:1
    Uncaught SyntaxError: Unexpected token <    styles.js:1
    Uncaught SyntaxError: Unexpected token <    vendor.js:1
    Uncaught SyntaxError: Unexpected token <    main.js:1
    

    here is my server.js file:

    .
    .
    .
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.use('/users', usersRouter);
    app.use('/auth', authRouter);
    
    // Catch all other routes and return the angular index file
    app.get('*', (req, res) => {
        res.sendFile(path.join(__dirname, 'client/dist/client/index.html'));
    });
    

    index.html file:

    <!doctype html>
    <html lang="en">
    
    <head>
      <meta charset="utf-8">
      <title>Client</title>
      <base href="./">
    
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="icon" type="image/x-icon" href="favicon.ico">
    </head>
    
    <body>
      <app-root></app-root>
      <script type="text/javascript" src="runtime.js"></script>
      <script type="text/javascript" src="polyfills.js"></script>
      <script type="text/javascript" src="styles.js"></script>
      <script type="text/javascript" src="vendor.js"></script>
      <script type="text/javascript" src="main.js"></script>
    </body>
    
    </html>
    

    There is no problem with ng serve and app will run smoothly and also when I just open index.html with browser it also works, I think it somehow relates to express server.

  • Mateusz Kocz
    Mateusz Kocz over 5 years
    This mostly depend on your application's setup. You could change where Angular builds the files by using ng build -o ./public or modyfing the Angular CLI configuration's outDir value.
  • Eliseo
    Eliseo over 5 years
    I don't know much about serverjs, but I supouse you can, in your get(*) get the req and if the req.url ends in .js server the file.js not the index.html
  • WhoIsCarlo
    WhoIsCarlo about 2 years
    I've been trying to figure this out for hours. Thank you for explaining this so clearly!!