Webpack – All about (1)

What can Webpack do?

  • Bundle multiple js files into 1 js file with correct js file order
  • Bundle multiple css, images,… files into 1 js file

How to config Webpack?

How to setup output bundle file?

const path = require('path');

module.exports = {
  entry: './src/index,js',      // Entry point where webpack can start to bundle js files
  output: {
    filename: 'bundle.js',      // Bundle js file name
    path: path.resolve(_dirname, './dist')    // Absolute path of folder where "bundle.js" is exported to
  },
}

How to setup dev server?

Use “webpack-dev-server”

module.exports = {
  mode: 'development',
  devServer: {
    port: 8081                  // This makes "webpack serve" run on http://localhost:8081
  },
  ...
}

How to insert bundle js into template HTML file?

Use html-webpack-plugin

  • Create a template HTML file
<!DOCTYPE html>
<html>

<head></head>

<body></body>

</html>
  • Setup Webpack
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  ...

  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
    })
  ]
}
  • Here is the result
<!DOCTYPE html>
<html>

<head></head>

<body><script src="bundle.js"></script></body>

</html>
  • Show js content into HTML body tag
    Edit HTML template
<!DOCTYPE html>
<html>

<head></head>

<body>
  <div id="root"></div>
</body>

</html>

Edit entry js file

const rootElement = document.getElementById('root');
rootElement.innerHTML = '<div>Testing</div>';

How to use React & Babel?

  • Install packages
yarn add react react-dom

yarn add babel-loader @babel/core @babel/plugin-proposal-class-properties @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react --dev
  • Create “babel.config.js”
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": "auto",
        "targets": {
          "browsers": [
            "last 2 Chrome versions",
            "last 2 Firefox versions",
            "last 2 Safari versions",
            "last 2 iOS versions",
            "last 1 Android version",
            "last 1 ChromeAndroid version",
            "ie 11"
          ]
        }
      }
    ],
    [
      "@babel/preset-react",
      {
        "runtime": "automatic"
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-runtime"
  ]
}
  • Configure webpack
  module: {
    rules: [
      // JavaScript: Use Babel to transpile JavaScript files
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      }
    ]
  }
  • Edit entry file using React & jsx
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(<App />, document.getElementById('root'))

How to use “dotenv-webpack”?

Install

yarn add dotenv-webpack --dev

Usage

  • Create .env.development file
// .env.development
DB_HOST=127.0.0.1
DB_PASS=foobar
S3_API=mysecretkey
  • Add it to webpack
// webpack.config.js
const Dotenv = require('dotenv-webpack');

module.exports = {
  ...
  plugins: [
    new Dotenv({
      path: './.env.development',
    }),
  ]
  ...
};
  • Use it in code
// file1.js
console.log(process.env.DB_HOST);
// '127.0.0.1'

How to setup proxy for localhost request?

How to make a request to /api/users proxy to http://localhost:3000/api/users?

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': 'http://localhost:3000',
    },
  },
};

How to omit “/api” in proxy request?

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
      },
    },
  },
};

How to proxy multiple paths to the same target?

module.exports = {
  //...
  devServer: {
    proxy: [
      {
        context: ['/auth', '/api'],
        target: 'http://localhost:3000',
      },
    ],
  },
};

How to override origin of host header?

The origin of the host header is kept when proxying by default, you can set changeOrigin to true to override this behaviour.

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
    },
  },
};

How to embed static Javascript into HTML template file?

Usually, you embed your static Javascript into HTML template file as below

// public/index.html

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8" />
    <script>
        window.myData = {
          MY_DATA: []
        }
    </script>
  </head>

  <body>

  </body>

</html>

you can make it a js file and embed it into HTML template file via webpack like this

// config/dev.config.js

window.myData = {
  API_END_POINT: 'https://xxxx.com/',
  MY_DATA: []
}
// webpack config file

const CopyPlugin = require('copy-webpack-plugin')

...

plugins: [
    new CopyPlugin({
      patterns: [{ from: 'config/dev.config.js', to: 'config.js' }],
    }),
]
<!-- HTML template file -->

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="utf-8" />
  </head>

  <body>

    <script src="config.js?v=#{version}"></script>

  </body>

</html>

How to use relative path without ‘../’

  • webpack config file
resolve: {
  alias: {
     Utilities: path.resolve(__dirname, 'src/utilities/'),
     Templates: path.resolve(__dirname, 'src/templates/')
  }
}

now you can use

// Instead of using relative paths
import config from '../../../utilities/configs'

// Now you can do
import config from 'Utilities/configs'
  • In order to make VSCode understand your new alias, edit “tsconfig.json”
{
    ...

    "baseUrl": ".",
    "paths": {
      "Utilities/*": ["./src/utilities/*"],
      "Templates/*": ["./src/templates/*"]
    },
}
  • Add package.json into “utilities” and “templates” folders
{
  "name": "utilities"
}
{
  "name": "templates"
}

How to bundle asset modules (Webpack 5)

webpack.config.js

...
module.exports = {
  ...
  output: {
    ...
    publicPath: 'dist/'
  }
  module: [
    {
       test: /\.(png|jpg)$/,
       type: 'assets/resource'
    }
  ]
}

how to set a public path for asset module

...
module.exports = {
  ...
  module: [
    {
       test: /\.(png|jpg)$/,
       type: 'assets/resource'
    }
  ]
}

Be the first to comment

Leave a Reply

Your email address will not be published.


*