Webpack a beginners guide
https://webpack.js.org/

Webpack a beginners guide

Webpack is a tool that lets you compile JavaScript modules. It’s also known as a module bundler. When webpack processes your application, it recursively builds a dependency graph that includes every module your application needs, then packages all of those modules into a small number of bundles - often only one - to be loaded by the browser.”In a short phrase, webpack allows you to package dependencies into bundles that will be understood by browsers.

It's probably the most popular tool to achieve this goal right now, and if you're remotely working with JavaScript you'll want to use it in your stack.

Given a large number of files, it generates a single file (or a few files) that run your app.

It can perform many operations:

  • Webpack helps you bundle your resources.
  • Webpack watches for changes and re-runs the tasks.
  • Webpack can run Babel transpilation to ES5, allowing you to use the latest JavaScript features without worrying about browser support.
  • Webpack can transpile CoffeeScript to JavaScript
  • Webpack can convert inline images to data URIs.
  • allows you to use require() for CSS files.
  • Webpack can run a development webserver.
  • Webpack can handle hot module replacement.
  • Webpack can split the output files into multiple files to avoid having a huge JS file to load in the first page hit.
  • Webpack can perform tree shaking.

Tree shaking means removing “dead code” from the bundle you ship to your users. If you add some code that you never use in your import statements, that’s not going to be sent to the users of your app, to reduce file size and loading time.

Webpack is not limited to being used on the front-end, but is useful in backend Node.js development as well.

There are many predecessors of Webpack and lots of similarities in what those tools and Webpack do. The main difference is that those tools are known as task runners, while Webpack was born as a module bundler.

Webpack is a more focused tool. You just need to specify an entry point to your app (it could even be an HTML file with script tags) and webpack analyzes the files and bundles them in a single JavaScript output file that includes everything you need to run the app.

Installing Webpack

Webpack can be installed globally or locally for each project.

Global install

Here’s how to install it globally with Yarn:

yarn global add webpack webpack-cli

with npm:

npm i -g webpack webpack-cli

once this is done, you should be able to run

webpack-cli

Local Install

Webpack can be installed locally as well. It’s the recommended setup, because Webpack can be updated per-project, and you have less resistance in using the latest features just for a small project rather than updating all the projects you have that use Webpack.

With Yarn:

yarn add webpack webpack-cli -D

with npm

npm i webpack webpack-cli --save-dev

Once this is done, add this to your package.json file:

{ 
  //... "scripts": { 
    "build": "webpack" 
  } 
}

Once this is done, you can run Webpack by typing

yarn build

in the project root.

Webpack configuration

By default, Webpack (starting from version 4) does not require any config if you respect these conventions:

  • the entry point of your app is ./src/index.js
  • the output is put in ./dist/main.js.
  • Webpack works in production mode

You can customize every little bit of Webpack of course, when you need. The Webpack configuration is stored in the webpack.config.js file, in the project root folder. if you like to have a Webpack generator then click here.

The entry point

By default the entry point is ./src/index.js This simple example uses the ./index.js file as a starting point:

module.exports = {
  /*...*/
  entry: './index.js'/*...*/
}

The output

By default the output is generated in ./dist/main.js. This example puts the output bundle into app.js:

module.exports = {
  /*...*/
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.js'
  }
  /*...*/
}

Using Webpack allows you to use import or require statements in your JavaScript code not just to include other JavaScript, but any kind of file (for example CSS).

Webpack aims to handle all our dependencies, not just JavaScript, and loaders are one way to do that.

For example, in your code you can use:

import 'style.css'

by using this loader configuration:

module.exports = {
  /*...*/module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' },
    }]
  }
  /*...*/
}

The regular expression targets any CSS file.

A loader can have options:

module.exports = {
  /*...*/module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }
  /*...*/
}

You can require multiple loaders for each rule:

module.exports = {
  /*...*/module: {
    rules: [
      {
        test: /\.css$/,
        use:
          [
            'style-loader',
            'css-loader',
          ]
      }
    ]
  }
  /*...*/
}

In this example, css-loader interprets the import 'style.css' directive in the CSS. style-loader is then responsible for injecting that CSS in the DOM, using a <style> tag.

The order matters, and it’s reversed (the last is executed first).

What kind of loaders are there? Many! You can find the full list here.

A commonly used loader is Babel, which is used to transpile modern JavaScript to ES5 code:

module.exports = {
  /*...*/module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
  /*...*/
}

This example makes Babel preprocess all our React/JSX files:

module.exports = {
  /*...*/module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  },
  resolve: {
    extensions: [
      '.js',
      '.jsx'
    ]
  }
  /*...*/
}

See the babel-loader options here.

Plugins

Plugins are like loaders, but on steroids. They can do things that loaders can’t do, and they are the main building blocks of Webpack.

Take this example:

module.exports = {
  /*...*/
  plugins: [
    new HTMLWebpackPlugin()
  ]
  /*...*/
}

The HTMLWebpackPlugin plugin does the job of automatically creating an HTML file and adding the output JS bundle path, so the JavaScript is ready to be served.

There are lots of plugins available.

One useful plugin, CleanWebpackPlugin, can be used to clear the dist/ folder before creating any output, so you don’t leave files around when you change the names of the output files:

module.exports = {
  /*...*/
  plugins: [
    new CleanWebpackPlugin(['dist']),
  ]
  /*...*/
}

The Webpack mode

This mode (introduced in Webpack 4) sets the environment on which Webpack works. It can be set to development or production (defaults to production, so you only set it when moving to development).

module.exports = {
  entry: './index.js',
  mode: 'development',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.js'
  }
}

Development mode:

  • builds very fast
  • is less optimized than production
  • does not remove comments
  • provides more detailed error messages and suggestions
  • provides a better debugging experience

Production mode is slower to build, since it needs to generate a more optimized bundle. The resulting JavaScript file is smaller in size, as it removes many things that are not needed in production.

I made a sample app that just prints a console.log statement.

Here’s the production bundle:

Here’s the development bundle:

Running Webpack

Webpack can be run from the command line manually if installed globally. But generally you write a script inside the package.json file, which is then run using npm or yarn.

For example this package.json scripts definition we used before:

"scripts": {
  "build": "webpack"
}

allows us to run webpack by running

npm run build

or

yarn run build

or simply

yarn build

Watching changes

Webpack can automatically rebuild the bundle when a change in your app happens, and it keeps listening for the next change.

Just add this script:

"scripts": {
  "watch": "webpack --watch"
}

and run

npm run watch

or

yarn run watch

or simply

yarn watch

One nice feature of the watch mode is that the bundle is only changed if the build has no errors. If there are errors, watch will keep listening for changes, and try to rebuild the bundle, but the current, working bundle is not affected by those problematic builds.

Handling images

Webpack allows you to use images in a very convenient way, using the file-loader loader.

This simple configuration:

module.exports = {
  /*...*/module: {
    rules: [
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          'file-loader'
        ]
      }
    ]
  }
  /*...*/
}

Allows you to import images in your JavaScript:

import Icon from './icon.png'

const img = new Image()
img.src = Icon
element.appendChild(img)

Where img is an HTMLImageElement. Check out the Image docs.

file-loader can handle other asset types as well, like fonts, CSV files, XML, and more.

Another nice tool to work with images is the url-loader loader.

This example loads any PNG file smaller than 8KB as a data URL.

module.exports = {
  /*...*/module: {
    rules: [
      {
        test: /\.png$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
      }
    ]
  }
  /*...*/
}

Process your SASS code and transform it to CSS

Using sass-loader, css-loader and style-loader:

module.exports = {
  /*...*/module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  }
  /*...*/
}

Generate Source Maps

Since Webpack bundles the code, Source Maps are mandatory to get a reference to the original file that raised an error. For example:

You tell Webpack to generate source maps using the devtool property of the configuration:

module.exports = {
  /*...*/
  devtool: 'inline-source-map',
  /*...*/
}

devtool has many possible values, the most used probably are:

  • none: adds no source maps
  • source-map: ideal for production, provides a separate source map that can be minimized, and adds a reference into the bundle, so development tools know that the source map is available. Of course you should configure the server to avoid shipping this, and just use it for debugging purposes
  • inline-source-map: ideal for development, inlines the source map as a Data URL

要查看或添加评论,请登录

Dr.MuthuKumaraswamy B的更多文章

  • AI Agents in Enterprise Production: Strategies for Success

    AI Agents in Enterprise Production: Strategies for Success

    AI and ML-driven agents are revolutionizing enterprise environments, but deploying them effectively in production…

  • Inside the Mind of an AI Agent: How It Works and Why It Matters

    Inside the Mind of an AI Agent: How It Works and Why It Matters

    Autonomous agents operate much like humans, relying on fundamental components such as identity, memory, planning, and…

  • Faster way to learn programming languages

    Faster way to learn programming languages

    Getting better at something faster isn't about skipping topics and being half-baked. I'm not showing you any shortcuts.

    3 条评论
  • Explaining AI: What Do Business Leaders Need to Care?

    Explaining AI: What Do Business Leaders Need to Care?

    AI and the challenge of model explainability. The use of artificial intelligence (AI) has become more widespread and is…

  • Vertex-AI

    Vertex-AI

    At the Google I/O developer conference earlier in May, Google Cloud announced the global launch of Vertex AI, a machine…

  • Multi-cloud redefined by Google

    Multi-cloud redefined by Google

    Ask anyone from the IT industry or anyone who observes the IT industry to name the top trends in the industry which…

    1 条评论
  • Axios Vs fetch what should you use

    Axios Vs fetch what should you use

    One of the basic tasks of any web application is to speak with servers through the Hypertext Transfer Protocol (HTTP)…

  • Async JS with Promises from Go

    Async JS with Promises from Go

    In JavaScript, Promise’s are the foundation of async/await. Lets take up an example, consider the below code, This will…

  • JavaScript Objects in Go and WebAssembly

    JavaScript Objects in Go and WebAssembly

    WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Implement your…

  • JavaScript Design Patterns

    JavaScript Design Patterns

    A pattern describes a Challange that happens over and another time in the environment, so describes the core of the…

社区洞察