Webpack packaged pictures-js-vue

Article directory

  • 1. Webpack packaged pictures
    • 1. Preparation for loading image resources
    • 2. Understand asset module type
    • 3.Use of asset module type
    • 4. The limit effect of url-loader
  • 2. babel
    • 1. Why babel is needed
    • 2.Usage of babel command line
    • 3.Use of babel plug-in
    • 4.babel’s default preset
    • 5.babel-loader
    • 6.babel-preset
  • 3. Load Vue files
    • 1.Write App.vue code
    • 2.App.vue packaging process
    • 3.@vue/compiler-sfc
  • 4. Resolution module analysis
    • 1.resolve module analysis
    • 2. File or folder
    • 3.extensions and alias configuration

1. Webpack packaged images

1. Preparation for loading image resources

In order to demonstrate that we can load images in our project, we need to use images in the project. There are two common ways to use images:

  • img element, set the src attribute;
  • For other elements (such as div), set the css attribute of background-image;

2. Understand asset module type

The webpack version we are currently using is webpack5:

  • Before webpack5, we needed to use some loader to load these resources, such as raw-loader, url-loader, and file-loader;
  • Starting from webpack 5, we can directly use the asset module type to replace the above loaders;

Asset module type replaces all these loaders by adding 4 new module types:

  • asset/resource sends a separate file and exports the URL.
    • Previously implemented by using file-loader;
  • asset/inline exports the data URI of an asset.
    • Previously implemented by using url-loader;
  • asset/source exports the source code of the resource
    • Previously implemented by using raw-loader;
  • asset automatically chooses between exporting a data URI and sending a separate file.
    • This was previously achieved by using url-loader and configuring resource volume limits;

3.Use of asset module type

For example, to load images, we can use the following method:

{<!-- -->
    test: /\.(png|svg|jpg|jpeg|gif)$/i,
    type: "asset/resource"
}

However, how can I customize the output path and file name of the file?

  • Method 1: Modify the output and add the assetModuleFilename attribute;
  • Method 2: In Rule, add a generator attribute and set filename;
output: {<!-- -->
    filename: "js/bundle.js",
    path: path.resolve(__dirname, "./dist"),
    assetModuleFilename: "img/[name].[hash:6][ext]"
}
{<!-- -->
    test: /\.(png|svg|jpg|jpeg|gif)$/i,
    type: "asset/resource",
    generator: {<!-- -->
        filename: "img/[name].[hash:6][ext]"
    }
}

Here we introduce some of the most commonly used placeholders:

  • [ext]: Process the extension of the file;
  • [name]: The name of the processed file;
  • [hash]: The content of the file is processed using the MD4 hash function to generate a 128-bit hash value (32 hexadecimal digits);

4. The limit effect of url-loader

During development, we often need to convert small pictures, but for large pictures, we can use pictures directly.

  • This is because small images can be requested together with the page after being converted to base64, reducing unnecessary request processes;
  • Large images are also converted, which will affect the page request speed;

We need two steps to achieve this:

  • Step 1: Change type to asset;
  • Step 2: Add a parser attribute, formulate the conditions for dataUrl, and add the maxSize attribute;
module.exports = {<!-- -->
    rules: [
        {<!-- -->
            test: /\.(png|svg|jpg|jpeg|gif)$/i,
            type: "asset",
            generator: {<!-- -->
                filename: "img/[name].[hash:6][ext]"
            },
            parser: {<!-- -->
                dataUrlCondition: {<!-- -->
                    maxSize: 100 * 1024
                }
            }
        }
    ]
}

2.babel

1. Why babel is needed

In fact, we rarely come into direct contact with babel during development, but babel is currently an indispensable part of front-end development:

  • During development, we want to use ES6+ syntax, use TypeScript, and develop React projects, all of which are inseparable from Babel;
  • Therefore, learning Babel is crucial for us to understand the transformation process of code from writing to online;

So, what exactly is Babel?

  • Babel is a toolchain that is mainly used in old browsers or environments to convert ECMAScript 2015+ code to backwards compatible versions of JavaScript;
  • Including: grammar conversion, source code conversion, etc.;

2.Using the babel command line

babel itself can be used as an independent tool (like postcss) and can be used alone without being configured with build tools such as webpack.

If we want to try using babel from the command line, we need to install the following libraries:

  • @babel/core: Babel’s core code must be installed;
  • @babel/cli: allows us to use babel on the command line;
npm install -D @babel/core @babel/cli

Use babel to process our source code:

  • src: is the directory of the source file;
  • –out-dir: Specify the folder dist to be output;
npx babel src --out-dir dist

3.Using the babel plug-in

For example, if we need to convert arrow function, then we can use the arrow function conversion related plug-in:

npm install @babel/plugin-transform-arrow-functions -D
npx babel src --out-dir dist --plugins=@babel/plugin-transform-arrow-functions

Check the converted result: we will find that const is not converted to var

  • This is because plugin-transform-arrow-functions does not provide such a function;
  • We need to use plugin-transform-block-scoping to complete such a function;
npm install @babel/plugin-transform-block-scoping -D
npx babel src --out-dir dist --plugins=@babel/plugin-transform-block-scoping
,@babel/plugin-transform-arrow-functions

4.babel’s default preset

But if there is too much content to be converted, setting each one is more troublesome. We can use preset:

  • We will talk more specifically about the meaning of default representation later;

Install @babel/preset-env preset:

npm install -D @babel/preset-env

Execute the following command:

npx babel src --out-dir dist --presets=@babel/preset-env

5.babel-loader

In actual development, we usually use it by configuring babel in Build Tool, such as in webpack.

Then we need to install the relevant dependencies:

  • If @babel/core has been installed before, there is no need to install it again here;
npm install babel-loader -D

We can set a rule to use our babel when loading js files:

module.exports = {<!-- -->
module: {<!-- -->
rules: [
{<!-- -->
test: /\.m?js$/,
use: {<!-- -->
loader: "babel-loader"
}
}
]
}
}

6.babel-preset

If we install and use plug-ins one by one, we need to manually manage a large number of babel plug-ins. We can directly provide a preset to webpack, and webpack will load the corresponding plug-in list according to our preset, and Pass it to babel.

For example, there are three common presets:

  • env
  • react
  • TypeScript

Install preset-env:

npm install @babel/preset-env
module.exports = {<!-- -->
    module: {<!-- -->
        rules: [
{<!-- -->
test: /\.m?js$/,
use: {<!-- -->
loader: "babel-loader",
                    options: {<!-- -->
                        presets: [
                            ["@babel/preset-env"]
                        ]
                    }
}
}
]
    }
}

3. Load Vue files

1. Write App.vue code

During development, we will write Vue-related code, and webpack can parse the Vue code:

  • Next we write our own App.vue code;
<template>
  <h2>{<!-- -->{ title }}</h2>
</template>

<script>
export default {<!-- -->
  data() {<!-- -->
    return {<!-- -->
      title: "I am the title"
    }
  }
}
</script>

2.App.vue packaging process

We will get an error when packaging the code: we need a suitable Loader to process the file.

At this time we need to use vue-loader:

npm install vue-loader -D

Configure it in webpack’s template rules:

{<!-- -->
    test: /\.vue$/,
    loader: "vue-loader"
}

3.@vue/compiler-sfc

Packaging will still report an error, this is because we must add @vue/compiler-sfc to parse the template:

npm install @vue/compiler-sfc -D

In addition, we need to configure the corresponding Vue plug-in:

const {<!-- --> VueLoaderPlugin } = require('vue-loader/dist/index')

module.exports = {<!-- -->
    module: {<!-- -->},
    plugins: [
        new VueLoaderPlugin()
    ]
}

Repackage to support App.vue writing method

In addition, we can also write other .vue files to write our own components;

4. resolve module analysis

1.resolve module analysis

resolve is used to set how the module is parsed:

  • During development, we will have various module dependencies. These modules may come from code written by ourselves or from third-party libraries;
  • resolve can help webpack find the appropriate module code that needs to be introduced from each require/import statement;
  • webpack uses enhanced-resolve to resolve file paths;

webpack can parse three file paths:

absolute path

  • Since the absolute path of the file has been obtained, no further parsing is required.

relative path

  • In this case, the directory where the resource file using import or require is located is considered to be the context directory;
  • The relative path given in import/require will be concatenated with this context path to generate the absolute path of the module;

module path

  • All directory search modules specified in resolve.modules;
    • The default value is [node_modules’], so files will be found in node_modules by default;
  • We can replace the initial module path by setting alias. The configuration of alias will be explained later;

2. File or folder

If it is a file:

  • If the file has an extension, the file is packaged directly;
  • Otherwise, the file extension will be resolved using the resolve.extensions option;

If it is a folder:

  • Will search in the folder according to the file order specified in the resolve.mainFiles configuration option;
    • The default value of resolve.mainFiles is [index’];
    • Then resolve the extension according to resolve.extensions;

3.extensions and alias configuration

Extensions means automatically adding extensions when parsing the file:

  • The default value is [.wasm’, .mjs’, .js’, .json’];
  • So if we want to add files such as .vue or jsx or ts to our code, we must write the extension ourselves;

Another very useful feature is to configure aliases:

  • Especially when the directory structure of our project is relatively deep, or the path of a file may require a path fragment like …/…/…/;
  • We can give some common paths an alias;
module.exports = {<!-- -->
  resolve: {<!-- -->
    extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
    alias: {<!-- -->
      utils: path.resolve(__dirname, "./src/utils")
    }
  },
}