2
votes

I am writing mt first cli app with node and I am facing some issues using babel to transpile my code. Basically, the app should start an express server which does ssr for react (similar to what next does). Somewhere in the process I use jsx syntax to render react component, so I need to transpile my code with babel. I am familiar on how to do this with babel cli or with webpack, howevere, I`m still facing issues implementing it for cli app.

In my package.json file I have:

  "bin": {
    "ssr": "./cli/ssr.js"
  },

and my ssr.js file:

    #!/usr/bin/env node

const server  = require('../server');
const routes = require('../../routes.js');
const createStore = require('redux').createStore;

const port = process.env.PORT || 3000;
const args = process.argv;

const defReducer = function(state={}, action){
    return state;
}
const configureStore = createStore(defReducer);

const instance = server(routes, configureStore, {}, {});

instance.listen(port, ()=>{
    console.log(`ssr server runs on localhost://${port}`);
});

and my server.js file is just a regular express server:

const express = require('express');
const cors = require('cors');
const renderer = require('./renderer');


module.exports = (Routes, createStore=()=>null, renderOpts={}, routerContext={})=>{
    const app = express();
    app.use(express.static('public'));
    app.use(cors());
    const port = process.env.PORT || 3000;

    app.get('*.js', (req, res, next) => {
        req.url = req.url + '.gz';
        res.set('Content-Encoding', 'gzip');
        next();
    });

    app.all('*', (req, res) => {

        const store = createStore();
        const promises = matchRoutes(Routes, req.path).map(( { route } ) => {
          if (typeof route.path === 'undefined') { return null; }
          let ctx = {store, module:route.module, req, res}
          return route.loadData ? route.loadData(ctx) : null;
        });

        Promise.all(promises).then(() => {
          const content = renderer(Routes, req, store, renderOpts, routerContext);

          if (context.url) {
            return res.redirect(301, context.url);
          }

          if (context.notFound) {
            res.status(404);
          }

          res.send(content);
        });
      });

      return app;
}

inside server.js file I call renderer which does:

        const content = renderToString(
        <Provider store={store}>
            <StaticRouter location={req.url} context={routerContext} basename= {opts.baseName || ''}>
                <div>{renderRoutes(Routes)}</div>
            </StaticRouter>
        </Provider>
    );

and this is where I get my syntax errors... I also tried to precompile my server.js file using webpack and babel and than link the bin command to the bundle.js output but it didn`t work I get this error popping on the screen:

enter image description here

What is the correct way of using babel with cli app?

1

1 Answers

0
votes

I followed a few steps here which you can find by going here https://babeljs.io/setup and clicking "CLI". I was able to transpile your server.js JSX following those steps, plus a couple extra in a fresh new folder. In order to transpile your code, here's what I did:

  1. Created a package.json by running (used all default values)

    npm init

  2. Created src\server.js file with your small <Provider> excerpt above

  3. Ran the following commands to install babel and the react libraries:

    npm install --save-dev @babel/core @babel/cli

    npm install --save-dev @babel/preset-env

    npm install --save-dev @babel/preset-react

  4. Created a .babelrc file with this single line:

    { "presets": ["@babel/preset-env", "@babel/preset-react"] }

  5. Created build script in package.json

    scripts: { "build": "babel src -d lib" }

  6. Ran the build:

    npm run-script build

And it successfully ran and transpiled the js into a new file within the lib folder. Try it out in a brand new folder and let me know how goes works for you