Webpack5学习笔记(基础篇)

Webpack

基本概念

是什么?

是一个静态资源打包工具。

可以做什么?

分为两种模式,分别是开发模式和生产模式。

  • 开发模式(development):仅能编译JS中的ES Module语法
  • 生产模式(product):既能编译JS中的ES Module语言,还能压缩JS代码

入门

  1. 创建项目(文件夹)
  2. 在项目所在文件夹中使用npm init生成package.json文件
  3. 使用npm install webpack webpack-cli -g安装webpack
  4. 使用npx webpack ./src/main.js(入口文件) --mode=development(指定打包模式)进行打包
  5. 在html文件中引用打包后的文件

配置参数

  • entry:指示webpack从哪个文件开始打包
  • output:指示webpack打包完的文件输出到哪里去,如何命名
  • loader:webpack本身只能处理js、json等资源,其它资源需要借助loader才能解析
  • plugins:拓展webpack的功能
  • mode:设置模式,即开发模式和生产模式

使用配置文件进行配置

  1. 在项目的根路径下常见名为webpack.config.js的文件
  2. 编写配置文件
// path是nodejs中的核心模块,专门用来处理路径问题
const path = require('path')

// 由于webpack是基于nodejs的,所以这里采用commonjs的模块化方式
module.exports = {
    // 入口:指示webpack从哪个文件开始打包(相对路径)
    entry: './src/main.js',
    // 输出:指示webpack打包完的文件输出到哪里去,如何命名
    output: {
        // 文件的输出路径(注意:这里要求用绝对路径)
        // __dirname是nodejs中的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, 'bundle'),
        // 输出文件名
        filename: 'utils.js'
    },
    // 加载器
    module: {
        rules: [
            // loader的相关配置
        ]
    },
    // 插件
    plugins: [
        // plugin的相关配置
    ],
    // 模式
    mode: 'development'
}

开发模式

顾名思义:即开发代码时的模式,主要做两件事情,

  • 一是编译代码,使得浏览器能够运行,处理样式资源、字体图标、html资源等webpack默认不能处理的资源
  • 代码质量检查,树立代码规范

处理样式资源

处理css资源
  1. 使用npm install --save-dev style-loader css-loader命令安装
  2. 在webpack.config.js文件中进行配置
module.exports = {
  module: {
    rules: [
      {
         test: /\.css$/,// 检测xxx.css文件
         use: [ // 执行顺序,从右到左(从下到上) // 对符合的文件进行处理
    	    'style-loader',// 将js中的css通过创建style标签添加到html文件中生效
        	'css-loader' // 将css资源编译成commonjs的模块到js中
    	]
      },
    ]
  }
}
  1. 使用npx webpack进行打包
处理less资源
  1. 使用npm install --save-dev less-loader less命令安装
  2. 在webpack.config.js文件中进行配置
module.exports = {
    ...
    module: {
        rules: [{
            test: /\.less$/,
            use: ["style-loader", // creates style nodes from JS strings
            	 "css-loader", // translates CSS into CommonJS
         		 "less-loader" // compiles Less to CSS
            }]
        }]
    }
};
  1. 使用npx webpack进行打包
处理sass资源
  1. 使用npm install sass-loader node-sass --save-dev命令安装
  2. 在webpack.config.js文件中进行配置
module.exports = {
  module: {
    rules: [{
      test: /\.scss$/,
      use: [ 
        "style-loader", // 将 JS 字符串生成为 style 节点
     	"css-loader", // 将 CSS 转化成 CommonJS 模块
      	"sass-loader" // 将 Sass 编译成 CSS
    	]
    }]
  }
};
  1. 使用npx webpack进行打包
处理stylus资源

1.使用npm install stylus stylus-loader --save-dev命令安装

2.在webpack.config.js文件中进行配置

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
            "style-loader",
            "css-loader",
            "stylus-loader" // compiles Styl to CSS
         ]
      },
    ],
  },
};

3.使用npx webpack进行打包

处理图片资源

从webpack5开始,图片加载器已经内置到了webpack中,故无需再安装其它加载器。

将指定规格的图片转化为base64格式

module.exports = {
  module: {
    rules: [
      {
            test: /\.(png|svg|jpe?g|gif|webp)$/,
            type: 'asset',
            parser: {
                // 优点,减少请求数量。缺点,体积会变的大一点
                dataUrlCondition: {
                    maxSize: 10 * 1024 // 小于10kb的图片转base64
                }
            }
      },
    ],
  },
};

改变文件的输出目录

// path是nodejs的核心模块,专门用来处理路径问题
const path = require('path')

// 由于webpack是基于nodejs的,所以这里采用commonjs的模块化方式
module.exports = {
    // 入口
    entry: './src/main.js',
    // 输出
    output: {
        // 所有文件的输出路径(注意:这里要求用绝地路径)
        // __dirname是nodejs中的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, 'bundle'),
        // 入口文件打包输出文件名
        filename: 'js/utils.js'
    },
    // 加载器
    module: {
        rules: [
                {
                    test: /\.(png|svg|jpe?g|gif|webp)$/,
                    type: 'asset',
                    parser: {
                        // 小于10kb的图片转base64
                        // 优点,减少请求数量。缺点,体积会变的大一点
                        dataUrlCondition: {
                            maxSize: 2 * 1024,
                        }
                    },
                    generator: {
                        // 输出图片名称
                        // hash:文件名
                        // ext:文件后缀名
                        // query:查询参数
                        // [hash:10] 文件名称取哈希值的前10位
                        filename:'static/images/[hash:1][ext][query]'
                    }
                }
            }
        ]
    },
    // 插件
    plugins: [
        // plugin的相关配置
    ],
    // 模式
    mode: 'development'
}

自动清空上次打包结果

module.exports = {
    // 入口
    entry: './src/main.js',
    // 输出
    output: {
        // 所有文件的输出路径(注意:这里要求用绝地路径)
        // __dirname是nodejs中的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, 'bundle'),
        // 入口文件打包输出文件名
        filename: 'js/utils.js',
        // 自动清空上次打包结果
        clean: true 
    }
}

引入字体图标

// 注意asset和asset/resource
{
    test: /\.(png|svg|jpe?g|gif|webp)$/,
    type: 'asset',// 当文件大小小于某个值时转化为base64格式
    parser: {
        // 小于10kb的图片转base64
        // 优点,减少请求数量。缺点,体积会变的大一点
        dataUrlCondition: {
            maxSize: 2 * 1024,
        }
    },
    generator: {
        // 输出图片名称
        // hash:文件名
        // ext:文件后缀名
        // query:查询参数
        // [hash:10] 文件名称取哈希值的前10位
        filename: 'static/images/[hash:10][ext][query]'
    }
},
{
    test: /\.(ttf|woff2?|mp3|avi)$/,
    type: 'asset/resource',// 相当于file-loader,对文件原封不动输出
    generator: {
        filename: 'static/font/[hash:10][ext][query]'
    }
}

EsLint

概念

用于检查语法

module.exports = {
  parserOption: { // 配置
    ecmaVersion: 6, // ES语法版本
    sourceType: 'module', // ES 模块化
    ecmaFeatures: { //ES其他特性
      jsx: true // 如果是react项目,则需要开始jsx语法
    }
  },
  rules: { // 定义规则,优先级高于extend中继承的规则
    // "off" 0 关闭规则
    // "warn" 1 使用警告级别的错误,不会导致程序推出
    // "error" 2 使用错误级别的错误,会导致程序推出
    semi: 'error', // 禁止使用分号
    'default-case': [
      'warn' // 要求switch语句中有default分支,否则警告
    ]
  },
  extends: [ //定义规则

  ]
}
用法
  1. 使用npm install eslint-webpack-plugin eslint --save-dev

  2. 在webpack.config.js文件中引入插件并使用

const ESLintPlugin = require('eslint-webpack-plugin')
module.exports = {
	//...
    // 插件
    plugins: [
        // plugin的相关配置
        new ESLintPlugin({
            // 检测那些文件
            context: path.resolve(__dirname, 'src')
        })
    ],
    // 模式
    mode: 'development'
}
  1. 在项目的根目录下创建.eslintrc.js文件并编写配置
module.exports = {
  // 继承recommended的标准
  extends: ['eslint:recommended'],
  env: {
    node: true, // 启用node中的全局变量
    browser: true // 启用浏览器中的全局变量
  },
  parserOptions: {
    ecmaVersion: 6, // ES语法版本
    sourceType: 'module', // ES 模块化
  },
  rules: {
    'no-var': 2,// 不能使用var定义变量
  }
}
插件

使用VSCode中的插件ESLInt可以在编译前检测代码的规范性,但是为了防止该插件检查打包后的文件,需要在项目的根目录下创建并编写.eslintignore文件,在该文件中编写不检查的目录

Babel

概念

代码转换,将代码转化为较多浏览器都能识别的代码

用法
  1. 使用npm install -D babel-loader @babel/core @babel/preset-env 命令安装
  2. 在webpack.config.js文件中配置该加载器
module: {
  rules: [
    {
        test: /\.js$/,
        exclude: /node_modules/, //排除node_modules中的js文件(这些文件不进行处理)
        loader: 'babel-loader',
        options: {
            presets: ['@babel/preset-env']
        }
    }
  ]
}
  1. 使用npx webpack进行打包

打包HTML资源

概念

将打包生成的js文件自动引入到html文件中,而不是手动引动

用法
  1. 使用npm install --save-dev html-webpack-plugin命令进行安装
  2. 在webpack.config.js配置该插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [new HtmlWebpackPlugin({
    // 模板:以public/index.html文件为模板,创建新的html文件
    // 新的html和原来的结构一次,会自动引入js资源
    template: path.resolve(__dirname, 'public/index.html')
})],
  1. 使用npx webpack进行打包

自动编译

概念

修改代码后需要使用npx webpack进行打包,使用该插件可以自动地打包,即自动监视src目录下的文件,一旦发生变化就重新打包

用法
  1. 使用npm install --save-dev webpack-dev-server进行安装
  2. 在webpack.config.js文件中配置
plugins:[],
devServer: {
    host: 'localhost', // 启动服务器域名
    port: '3000', // 启动服务器端口号
    open: true // 是否打开浏览器
},
// 模式
mode: 'development'
  1. 使用npx webpack serve该命令启动
注意

使用该方式打包不会生成资源,即不会输出bundle/xxx等资源,是在内存中运行的

生产模式

开发模式和生产模式的切换

在项目的根目录下创建一个文件夹,用于存放开发模式的配置生产模式的配置,前者取名为webpack.dev.js,后者取名为webpack.prod.js

开发模式
const path = require('path')
const ESLintPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/main.js',
    // 当为开发模式时,使用的是服务器,无输出文件,故可不指定输出位置
    output: {
        // 若使用dev-serve构建服务器,则此参数无效,故可以设置为undefined
        // path: path.resolve(__dirname, 'bundle'),
        // html中会引用此文件名,若不设置,默认为main.js
        filename: undefined
    },
    module: {
        rules: [
            // loader的相关配置
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.less$/,
                use: ["style-loader", "css-loader", "less-loader"]
            },
            {
                test: /\.s[ac]ss$/,
                use: ["style-loader", "css-loader", "sass-loader"]
            },
            {
                test: /\.styl$/,
                use: ["style-loader", "css-loader", "stylus-loader"]
            },
            {
                test: /\.(png|svg|jpe?g|gif|webp)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 2 * 1024,
                    }
                },
                generator: {
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            {
                test: /\.(ttf|woff2?|mp3|avi)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'static/font/[hash:10][ext][query]'
                }
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env']
                }
            }
        ]
    },
    plugins: [
        new ESLintPlugin({
            context: path.resolve(__dirname, '../src')
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html')
        })
    ],
    devServer: {
        host: 'localhost', // 启动服务器域名
        port: '3000', // 启动服务器端口号
        open: true // 是否打开
    },
    mode: 'development'
}

使用npx webpack serve --config ./config/webpack.dev.js命令启动

生产模式
const path = require('path')
const ESLintPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, '../bundle'),
        filename: 'main.js',
        clean: true
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.less$/,
                use: ["style-loader", "css-loader", "less-loader"]
            },
            {
                test: /\.s[ac]ss$/,
                use: ["style-loader", "css-loader", "sass-loader"]
            },
            {
                test: /\.styl$/,
                use: ["style-loader", "css-loader", "stylus-loader"]
            },
            {
                test: /\.(png|svg|jpe?g|gif|webp)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 2 * 1024,
                    }
                },
                generator: {
                    filename: 'static/images/[hash:10][ext][query]'
                }
            },
            {
                test: /\.(ttf|woff2?|mp3|avi)$/,
                type: 'asset/resource',
                generator: {
                    filename: 'static/font/[hash:10][ext][query]'
                }
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env']
                }
            }
        ]
    },
    plugins: [
        new ESLintPlugin({
            context: path.resolve(__dirname, '../src')
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html')
        })
    ],
    mode: 'production'
}

使用npx webpack --config ./config/webpack.prod.js命令打包

合并命令

在package.json文件中的scripts中进行配置

{
  "scripts": {
    "dev": "npx webpack serve --config ./config/webpack.dev.js",
    "build":"npx webpack --config ./config/webpack.prod.js"
  },
}

在命令行窗口使用npm run dev | npm run build| npm start启动

提取css为单独文件

  1. 使用npm install --save-dev mini-css-extract-plugin安装插件
  2. 在webpack.config.js中进行配置
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
 	//...
    module: {
     	rules: [
            {
                test: /\.css$/,
                //将之前的style-loader替换为MiniCssExtractPlugin.loader
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
        ]
    }
    plugins;[
    	 new MiniCssExtractPlugin({
            filename: 'static/css/main.css'
        })
    ]
}
  1. 使用命令打包

样式的兼容性处理

  1. 使用npm install --save-dev postcss-loader postcss postcss-preset-env命令安装包
  2. 在webpack.config.js中进行配置
module.exports = {
	// ,,,
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader',
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            plugins: [
                                [
                                    "postcss-preset-env",
                                ],
                            ],
                        },
                    }
                }]
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            plugins: [
                                [
                                    "postcss-preset-env",
                                ],
                            ],
                        },
                    }
                }, "less-loader"]
            },
            {
                test: /\.s[ac]ss$/,
                use: [MiniCssExtractPlugin.loader, "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            plugins: [
                                [
                                    "postcss-preset-env",
                                ],
                            ],
                        },
                    }
                }, "sass-loader"]
            },
            {
                test: /\.styl$/,
                use: [MiniCssExtractPlugin.loader, "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        postcssOptions: {
                            plugins: [
                                [
                                    "postcss-preset-env",
                                ],
                            ],
                        },
                    }
                }, "stylus-loader"]
            }
        ]
    },
	// ...
  1. 在package.json文件中设置兼容性级别
{
  ...   
  "browserslist": [
    "last 2 version",
    "> 1%",
    "not dead"
  ]
}
  1. 使用命令打包

将多个样式的loader封装为函数

function getStyleLoader(pre) {
    return [
        MiniCssExtractPlugin.loader,
        'css-loader',
        {
            loader: "postcss-loader",
            options: {
                postcssOptions: {
                    plugins: [
                        [
                            "postcss-preset-env",
                        ],
                    ],
                },
            }
        },
        pre].filter(Boolean)
}
module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, '../bundle'),
        filename: 'main.js',
        clean: true
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: getStyleLoader()
            },
            {
                test: /\.less$/,
                use: getStyleLoader('less-loader')
            },
            {
                test: /\.s[ac]ss$/,
                use: getStyleLoader('sass-loader')
            },
            {
                test: /\.styl$/,
                use: getStyleLoader('stylus-loader')
            }
        ]
    },
}

Css压缩

  1. 使用命令npm install css-minimizer-webpack-plugin --save-dev安装插件
  2. 在webpack.config.js中进行配置
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
plugins: [
    new CssMinimizerPlugin()
],
  1. 使用命令打包

你可能感兴趣的:(Webpack5,学习,webpack,javascript)