...see more

In the root of the ASP.NET Core web project, create the following folder structure:

ClientApp/
  src/
    index.js
    components/
We use the ClientApp folder and structure to follow common naming conventions.
...see more

Open a new command prompt window and navigate to the ClientApp folder. 

The package.json file is used in Nodejs projects to store general information about the project (like its name, version, etc) and track what dependencies the project needs (so that anyone can install them all at once).

To create a “default” package.json file, type the “npm init” command with the y option:

npm init -y
The “-y” option uses default options.

Once the npm init command is done, you should have a package.json file under your project directory (and nothing else, yet).

The package.json file can now be used to "document" any dependencies you add to your project. This happens automatically when you npm install anything.

If the command was successful, it should have created a package.json file with contents similar to this:

{
 "name": "demo",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [],
 "author": "",
 "license": "ISC"
 }
...see more

Since you’ll be writing your code in multiple modules (files) and it will depend on other modules (like React), you need a module bundler to translate all these modules into something that can work in all browsers today. You can use Webpack for that job.

To install the packages you need for Webpack (which is also a “module”), type the following command:

npm i -D webpack webpack-cli

If the command ran successfully, it should have created a new folder named “node_modules” in your project folder and downloaded several modules into this folder (into various folders), of course including the Webpack package as well. 

Instead of a run-time dependency, the “ — save-dev” option adds a “dev dependency” to the package.json file. This indicates that the Webpack package is only useful during development. That would make sense, as once we have created the “bundles” as we require, we would use them directly in production. The package.json file should look similar to this:

{
 // ...
 },
 "devDependncies": {
  "webpack": "^5.69.1",
  "webpack-cli": "^4.9.2"
 }
}

Official website: webpack bundle your styles

...see more

Babel is a transpiler. The transpiler transforms ES6 code to use ES5 syntax that older browsers can understand. While Babel itself is very feature-rich and can be used independently, for our purposes, we can use the corresponding babel “loaders” to do the job.

Webpack is just a generic module bundler. You need to configure it with loaders to transform code from one state into the other.

Before we can use any loaders, we need first to install them. For our purpose, we will have to install the relevant babel loaders. Use the following command to install the babel loaders and the “presets”.

npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-react

If the command ran successfully, these loaders would be installed in the node_modules folder and the package.json would be modified.

...see more

A priceless development dependency is ESLint.

ESLint is a code quality tool and if you don’t use it, your code will not be as good as it could be.

Since Babel is part of this stack, you need to configure ESLint to parse through what Babel is going to parse through. You should also use the main recommended ESLint configurations in addition to those recommended for React projects. Here are the packages you need for that:

npm i -D eslint @babel/eslint-parser eslint-plugin-react eslint-plugin-react-hooks

Updating babel-eslint to @babel/eslint-parser for React apps | Tim Addison (tjaddison.com)

...see more

The most popular testing library that’s usually used with React is Jest. Install that if you plan to write tests for your React project (and you should!). You’ll also need babel-jest and a test renderer like react-test-renderer:

npm i -D jest babel-jest react-test-renderer
...see more

The frontend dependencies you need are React and ReactDOM. Install them next:

npm i -D react react-dom

Install the Babel preset to process React JSX code:

npm i -D @babel/preset-react
...see more

To configure Webpack to bundle your application into a single bundle file, create a webpack.config.js file under the root of the project and put the following module.exports object in it:

webpack.config.js

const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/index.jsx',
    output: {
        path: path.resolve(__dirname, '../wwwroot/js'),
        filename: 'snippset.js'
    },
    module: {
        rules: [
            {
                test: /\.jsx$/,
                exclude: /(node_modules)/,
                use: [{
                    loader: 'babel-loader',
                }
                ]
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.jsx']
    }
};
Webpack has certain defaults on which JavaScript file to start with. It looks for a src/index.js file. It’ll also output the bundle to dist/main.js by default. If you need to change the locations of your src and dist files, you’ll need a few more configuration entries in webpack.config.js.
...see more

To configure Babel to compile JSX and modern JavaScript code, create a babel.config.js file under the root of the project and put the following module.exports object in it:

babel.config.js

module.exports = {
  presets: ['@babel/preset-react', '@babel/preset-env'],
};

These presets were already installed above. The env preset is the one Babel uses to transform modern JavaScript (and it’s configurable if you need to target just modern browsers and make the bundle smaller). The react preset is for the mighty JSX extension.

...see more

To configure ESLint, you need to add a .eslintrc.js file in the root of the project. This file will naturally depend on your code style preferences, but definitely start it with the recommended configurations and then customize them as needed:

.eslintrc.js

module.exports = {
  parser: 'babel-eslint',
  env: {
    browser: true,
    commonjs: true,
    es6: true,
    node: true,
    jest: true,
  },
  parserOptions: {
    ecmaVersion: 2020,
    ecmaFeatures: {
      impliedStrict: true,
      jsx: true,
    },
    sourceType: 'module',
  },
  plugins: ['react', 'react-hooks'],
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
  ],
  settings: {
    react: {
      version: 'detect',
    },
  },
  rules: {
    // You can do your customizations here...
    // For example, if you don't want to use the prop-types package,
    // you can turn off that recommended rule with: 'react/prop-types': ['off']
  },
};
You should make your editor highlight any ESLint issues for you on save! All the major editors today have plugins to do that. You should also make your editor auto-format code for you on save as well using Prettier. Prettier works great with ESLint.
...see more

In your package.json file you should have a scripts section. If you generated the file with the npm init defaults you’ll have a placeholder "test" script in there. You should change that to work with Jest.

Add more scripts in there to build the scripts with runner for Webpack.

{
 // ...
 "scripts": {
    "build:dev": "webpack --stats verbose",
    "build:prd": "webpack build --config ./webpack.config.prd.js --stats verbose",
    "build:watch": "webpack --watch",
    "test": "jest"
 },

The --mode=development flag is to make Webpack generate a development-friendly bundle. Run Webpack with --mode=production in production.

The --watch flag in the command above is to run Webpack in watch mode 

Command Line Interface | webpack

...see more

webpack.config.prd.js

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  mode: 'production',
  entry: './src/index.jsx',
  output: {
    path: path.resolve(__dirname, '../wwwroot/dist/js'),
    filename: 'snippset.min.js'
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          format: {
            comments: false,
          },
        },
        extractComments: false,
      }),
    ],
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /(node_modules)/,
        use: [{
          loader: 'babel-loader',
        }
        ]
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx']
  }
};

Remove Comments

Comments