webpack配置

一、介绍

1.什么是webpack

       是前端工程化的具体解决方案

2.主要功能

       提供了友好的前端模块化开发支持,以及代码混淆、处理浏览器端js的兼容,性能优化等强大功能

3.优点:

       提高了开发效率和可维护性,降低了开发难度

4.用于:

       目前Vuereact 等前端项目,基本上都是基于webpack进行工程化开发的

二、使用

1.新建一个文件夹

文件夹只能是英文和数字,不能有“中文” . “空格”

2.初始包管理配置文件

在文件的路径上打上cmd进入dos环境。然后输入

npm init -y

这一步是为了初始 包管理配置文件

文件夹csdn中生成一个webpack,json的文件 

3.安装webpack

npm install webpack webpack-cli -D

-D等价于—save-dev。意为:本地安装

 扩展:-g 意为:全局安装

             install:可以缩写为 i

4.src配置

新建src 空白文件夹,用于存储源代码。(程序员写的源代码都存储于src中)

创建  index.js和 indexUntil.js index.js依赖indexUntil.js

indexUntil.js 写入

var show = console.log('show');
module.exports = {
    show
}

index.js 写入

require("./indexUntil")

然后在dos中输入 

webpack ./src/js/index.js -o ./dist

就会生成dist 文件夹

 然后再在 src 文件夹中创建一个html文件夹把这个main.js文件导入就可以了

webpack会以 ./src/js/index.js 为入口文件开始打包,打包后输出到 ./dist 整体打包环境,是开发环境

结论:

  1. webpack 本身能处理 js/json 资源不能处理 css/img 等其他资源,需借助loader

  2. 生产环境和开发环境将 ES6 模块化编译成浏览器能识别的模块化,但是不能处理 ES6 的基本语法转化为 ES5(需要借助 loader)

  3. 生产环境比开发环境多一个压缩 js 代码

新建一个info.js使用ES6的语法导出

info.js

//es6语法导出
export default {
  name:'zzz',
  age:24,
}

main.js导入info.js

//使用es6语法导入
import info from './info.js'

console.log(info.name)
console.log(info.age)

再次使用webpack ./src/js/index.js -o ./dist ,重新打包

5、Webpack .config.js配置

在根目录创建一个名为

webpack.config.js

的文件,在里面用node.js语言,导出一个webpack配置对象(config:意为配置,module意为模块 export意为出口)。           

//path是node里面的一个模块不导入不能用
const path = require('path')

module.exports = {
    //mode意为 模式。而webpack模式有两种一种是 development:开发者模式;另一种是production生产模式(上线模式)
    mode: 'development',
    entry: './src/index.js', //入口文件
    output: {
        //动态获取打包后的文件路径,path.resolve拼接路径
        //__dirname就表示这个文件所处的目录,即根目录
        path: path.resolve(__dirname, 'dist'), 
        filename: 'bundle.js', //打包后的文件名
    },
}

注:

1.path是node里面的一个模块不导入不能用

2.mode意为 模式。而webpack模式有两种一种是 development:开发者模式;另一种是production上线模式

3.entry:入口文件

4.动态获取打包后的文件路径,path.resolve拼接路径

5.__dirname就表示这个文件所处的目录,即根目录

6.filemane 打包后名字

然后在package.json中的‘scripts’中写上

"dev":"webpack"

这样写是声明一 个脚本 ,其中dev可以随意起名scripts:意为脚本)

然后就可以通过输入 npm run dev 启动。

补充:

        entry:文件入口,即wepack以哪个文件夹为入口,用以分析构建内部依赖图,并进行打包

        output:文件出口,即打包好的文件输出在哪,名叫什么

        loader:webpack本身无法识别js以外的程序,所以要借助loader来处理

        plugins:插件用于执行范围更广的任务,插件的范围包括从打包和压缩,一直到重新定义环境中的变量等。

        mode:Webpack使用相应模式的配置。分为development和production两种模式。其中development是开发模式,能让代码本地运行的环境;production是生产模式,能让代码优化运行的环境。

        webpack.config.js:webapck的配置文件,当你打包构建前,是先进入webpack.config.js文件中读取文件中的配置,然后基于这些配置来打包项目。

6.css文件处理

1.创建css文件index.css

body {
    background-color: red;
}

2.在index.js文件中引入

require("../css/index.css")

3.在dos中下载style-loader和css-loader

npm install --save-dev css-loader style-loader

4.在webpack.config.js中配置

module: {
        rules: [{
            test: /\.css$/, //正则表达式匹配css文件
            //css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader
            use: [{
                    loader: 'style-loader'
                },
                {
                    loader: 'css-loader'
                }
            ] //使用loader
        }]
    }

其中 test: /\.css$/,是正则表达式。

test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。$是结束的意思。

css-loader用于加载css文件,style-loader用于将样式解析到dom文件中。

最后运行npm run dev。css配置结束

7.less文件处理

1.在css文件夹中新增一个less文件

special.less

@fontSize:50px;//定义变量字体大小
@fontColor:orange;//定义变量字体颜色
body{
  font-size: @fontSize;
  color: @fontColor;
}

2.index.js中导入less文件模块

//5.依赖less文件
require('./css/special.less')
//6.向页面写入一些内容
document.writeln("hello,zzzz!")

3.安装使用less-loader

npm install --save-dev less-loader less

4.在webpack.config.js中配置

module: {
        rules: [{
            test: /\.less$/, //正则表达式匹配css文件
            //css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader
            use: [{
                    loader: 'style-loader'
                },
                {
                    loader: 'css-loader'
                }
                ,
                {
                    loader: 'less-loader'
                }
            ] //使用loader
        }]
    }

8. 图片文件的处理

1.安装loader

npm install --save-dev file-loader url-loader

2.在webpack.config.js中配置

module: {
        rules: [{
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[hash][ext][query]'
                } //把打包的图片放到images文件夹
            }]
    }
图片大小小于8kb,就会被base64处理(此时使用url-loader),优点:减少请求数量(减轻服务器压力),缺点:图片体积会更大(文件请求速度更慢)

9. 打包html资源

1.为什么需要打包html资源

直接在src中的html文件中写入标签会报错,所以需要引用插件

2.引用node.js中的插件

const HtmlWebpackPlugin = require('html-webpack-plugin');
//同时要在下面配置
plugins: [new HtmlWebpackPlugin({
		template: './src/index.html' 
	})],

其中 const HtmlWebpackPlugin = require('html-webpack-plugin');  是导入一个html的插件,使HtmlWebpackPlugin成为构造函数。

plugins: [new HtmlWebpackPlugin({
        template: './src/index.html' 
    })]

通过plugins节点,在其中创建html的实例对象,用以使html插件生效。

以下是完整代码段

const path = require('path')
//导入html插件得到一个构造函数
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'production',
    //mode: 'development',
    entry: './src/js/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/main.js'
    },
   
    plugins: [
        //根据构造函数创建html的一个实例对象
        new HtmlWebpackPlugin({
            //源文件的存放路径
            template: './src/index.html',
            //生成文件的存放路径和文件名
            filename: 'index.html' 
        })
    ],
    module: {
        rules: [{
                test: /\.css$/,
                use: [{
                        loader: 'style.loader'
                    },
                    {
                        loader: 'css-loader'
                    }
                ]
            }, {
                test: /\.less$/,
                use: [{
                         loader: 'style.loader'
                    },
                    {
                        loader: 'css-loader'
                    },
                    {
                        loader: 'less-loader'
                    }
                ]
            }, {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[hash][ext][query]'
                } //把打包的图片放到images文件夹
            },
            
        ]
    },

3.下载html-loader和html-webpack-plugin 插件

npm install --save-dev html-loader html-webpack-plugin

4.在module中配置

{
				test: /\.html$/i,
				loader: "html-loader",
			},

10.打包其他资源

在以上的配置结束后,剩下的格外简单,只要白这些代码导入module(模块)就可以了

// 打包其他资源(除了html/js/css资源以外的资源)
      {
        // 排除html|js|css|less|jpg|png|gif文件
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        // file-loader:处理其他文件
        loader: 'file-loader',
        options: {
          name: '[hash:10].[ext]',
          outputPath: 'fonts',
        },
      },

或者

{
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
        generator: {
					filename: 'fontss/[hash][ext][query]'
				}
 },

11.开发服务器自动化

1. devServer作用

开发服务器 devServer:用来自动化,不用每次修改后都重新输入webpack打包一遍(自动编译,自动打开浏览器,自动刷新浏览器)


特点:只会在内存中编译打包,不会有任何输出(不会像之前那样在外面看到打包输出的build包,而是在内存中,关闭后会自动删除)

2.下载webpack-dev-server

npm install --save-dev webpack-dev-server

3.此代码和module同级

 devServer: {
    // 项目构建后路径
    //contentBase: resolve(__dirname, 'build'),
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 3000,
    // 自动打开浏览器
    open: true,
  },


4.启动devServer指令为:

npx webpack-dev-server

5.此时全代码为

//path是node里面的一个模块不导入不能用
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    //mode意为 模式。而webpack模式有两种一种是 development:开发者模式;另一种是production生产模式(上线模式)
    mode: 'development',
    entry: './src/js/index.js', //入口文件
    output: {
        //动态获取打包后的文件路径,path.resolve拼接路径
        //__dirname就表示这个文件所处的目录,即根目录
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/bundle.js', //打包后的文件名
    },
    plugins: [
        //根据构造函数创建html的一个实例对象
        new HtmlWebpackPlugin({
            //源文件的存放路径
            template: './src/index.html',
            //生成文件的存放路径和文件名
            filename: 'index.html',
        })
    ],
    module: {
        rules: [{
                test: /\.css$/, //正则表达式匹配css文件
                //css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader
                use: [{
                        loader: 'style-loader'
                    },
                    {
                        loader: 'css-loader'
                    }
                ] //使用loader
            },
            {
                test: /\.less$/, //正则表达式匹配css文件
                //css-loader只负责css文件加载,不负责解析,要解析需要使用style-loader
                use: [{
                        loader: 'style-loader'
                    },
                    {
                        loader: 'css-loader'
                    },
                    {
                        loader: 'less-loader'
                    }
                ] //使用loader
            }, {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[hash][ext][query]'
                } //把打包的图片放到images文件夹
            }, {
                test: /\.html$/i,
                loader: "html-loader",
            },
        ]
    },
    devServer: {
        // 项目构建后路径
        //contentBase: resolve(__dirname, 'build'),
        // 启动gzip压缩
        compress: true,
        // 端口号
        port: 3000,
        // 自动打开浏览器
        open: true,
    },


}

注:此时 

plugins: [
        //根据构造函数创建html的一个实例对象
        new HtmlWebpackPlugin({
            //源文件的存放路径
            template: './src/index.html',
            //生成文件的存放路径和文件名
            filename: 'index.html',
        })
    ]

中的 filename: 'index.html', 必须是index.html

12.压缩css并将css从js中提取出来

1.下载插件

npm install --save-dev mini-css-extract-plugin css-minimizer-webpack-plugin

其中插件 css-minimizer-webpack-plugin 优化和压缩 CSS,而 mini-css-extract-plugin 用于把CSS 提取到单独的文件

2.引用插件并配置

const MiniCssExtractPlugin = require('mini-css-extract-plugin') //提取css成单独文件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); //压缩css
 plugins: [
       new MiniCssExtractPlugin({
            filename: 'css/bundle.css'
        }),
        //提取css 提取时要使用MiniCssExtractPlugin.loader 而且不要对其加引号
        new CssMinimizerPlugin()
    ]

将style-loader改为MiniCssExtractPlugin.loader(注MiniCssExtractPlugin.loader不加引号)

{
                test: /\.css$/,
                use: [{
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                        loader: 'css-loader'
                    }
                ]
            }, {
                test: /\.less$/,
                use: [{
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                        loader: 'css-loader'
                    },
                    {
                        loader: 'less-loader'
                    }
                ]
            }

13.postcss

1.为什么用postcss

postcss-loader能处理css兼容性

2.下载

npm install --save-dev postcss-loader postcss postcss-preset-env

3.配置

const commonCssLoader = [
    // 这个loader取代style-loader。作用:提取js中的css成单独文件然后通过link加载
    MiniCssExtractPlugin.loader,
    // css-loader:将css文件整合到js文件中
    // 经过css-loader处理后,样式文件是在js文件中的
    // 问题:1.js文件体积会很大2.需要先加载js再动态创建style标签,样式渲染速度就慢,会出现闪屏现象
    // 解决:用MiniCssExtractPlugin.loader替代style-loader
    'css-loader',
    {
        loader: 'postcss-loader',
        options: {
            postcssOptions: {
                plugins: [
                    [
                        'postcss-preset-env', //这个需要安装npm install postcss-preset-env否则不能生效
                        {
                            // 其他选项
                        },
                    ],
                ],
            },
        },
    },
]
module: {
        rules: [{
                test: /\.css$/,
                use: [...commonCssLoader],
            }, {
                test: /\.less$/,
                use: [...commonCssLoader,
                    'less-loader'
                ]
            }
            
        ]
    },

/*
    postcss-loader:css兼容性处理:postcss --> 需要安装:postcss-loader postcss-preset-env
    postcss需要通过package.json中browserslist里面的配置加载指定的css兼容性样式
    在package.json中定义browserslist:browserslist里面的注释一定要删掉 否则报错
    "browserslist": {
      // 开发环境 --> 设置node环境变量:process.env.NODE_ENV = development
      "development": [ // 只需要可以运行即可
        "last 1 chrome version",
        "last 1 firefox version",
        "last 1 safari version"
      ],
      // 生产环境。默认是生产环境
      "production": [ // 需要满足绝大多数浏览器的兼容
        ">0.02%",
        "not dead",
        "not op_mini all"
      ]
    },
  */

删除注释后的代码

"browserslist": {
		"development": [
			"last 1 chrome version",
			"last 1 firefox version",
			"last 1 safari version"
		],
		"production": [
			">0.02%",
			"not dead",
			"not op_mini all"
		]
	}

 14.js压缩和html压缩

js压缩

把mode中的 development 改为 production 就自动压缩了

html压缩

 new HtmlWebpackPlugin({
            //源文件的存放路径
            template: './src/index.html',
            filename: 'index.html'
        })

中加入

 minify: {
                // 移除空格
                collapseWhitespace: true,
                // 移除注释
                removeComments: true,
            }

15.使用babel-loader来处理js的兼容性问题

用于处理js的高级语言

1.下载

npm install -D babel-loader @babel/core @babel/preset-env

2.代码

 {
                //npm install -D babel-loader @babel/core @babel/preset-env
                test: /\.js$/,
                exclude: /node_modules/,// 忽略node_modules
                loader: 'babel-loader',
                options: {
                    presets: [
                        ['@babel/preset-env']
                    ]
                }
            }

最后完整的代码

//path是node里面的一个模块不导入不能用
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin') //提取css成单独文件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); //新的压缩css

const commonCssLoader = [
    // 这个loader取代style-loader。作用:提取js中的css成单独文件然后通过link加载
    MiniCssExtractPlugin.loader,
    // css-loader:将css文件整合到js文件中
    // 经过css-loader处理后,样式文件是在js文件中的
    // 问题:1.js文件体积会很大2.需要先加载js再动态创建style标签,样式渲染速度就慢,会出现闪屏现象
    // 解决:用MiniCssExtractPlugin.loader替代style-loader
    'css-loader',
    {
        loader: 'postcss-loader',
        options: {
            postcssOptions: {
                plugins: [
                    [
                        'postcss-preset-env', //这个需要安装npm install postcss-preset-env否则不能生效
                        {
                            // 其他选项
                        },
                    ],
                ],
            },
        },
    },
]

module.exports = {
    //mode意为 模式。而webpack模式有两种一种是 development:开发者模式;另一种是production生产模式(上线模式)
    mode: 'development',
    entry: './src/js/index.js', //入口文件
    output: {
        //动态获取打包后的文件路径,path.resolve拼接路径
        //__dirname就表示这个文件所处的目录,即根目录
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/bundle.js', //打包后的文件名
    },
    plugins: [
        //根据构造函数创建html的一个实例对象
        new HtmlWebpackPlugin({
            //源文件的存放路径
            template: './src/index.html',
            filename: 'index.html',
            minify: {
                // 移除空格
                collapseWhitespace: true,
                // 移除注释
                removeComments: true,
            }
        }),
        new MiniCssExtractPlugin({
            filename: 'css/bundle.css'
        }),
        //提取css 提取时要使用MiniCssExtractPlugin.loader 而且不要对其加引号
        new CssMinimizerPlugin()
    ],
    module: {
        rules: [{
                test: /\.css$/,
                use: [...commonCssLoader],
            }, {
                test: /\.less$/,
                use: [...commonCssLoader,
                    'less-loader'
                ]
            }, {
                test: /\.html$/i,
                loader: "html-loader",
            }, {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[hash][ext][query]'
                } //把打包的图片放到images文件夹
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'fonts/[hash][ext][query]'
                } //把打包的图片放到fonts文件夹			
            },
            {
                //npm install -D babel-loader @babel/core @babel/preset-env
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: [
                        ['@babel/preset-env']
                    ]
                }
            }

        ]
    },
    devServer: {
        // 项目构建后路径
        //contentBase: resolve(__dirname, 'build'),
        // 启动gzip压缩
        compress: true,
        // 端口号
        port: 3000,
        // 自动打开浏览器
        open: true,
        hot: true
    },
    //开发调试阶段精准定位哪个文件错误
    devtool: 'eval-source-map'
    //上线阶段精准定位哪个文件错误,但不会暴漏源码
    //devtool: 'nosources-source-map'


}

三、webpack优化配置

1. HMR(模块热替换)

HMR: hot module replacement 热模块替换 / 模块热替换

作用:一个模块发生变化,只会重新打包构建这一个模块(而不是打包所有模块) ,极大提升构建速度

代码:只需要在 devServer 中设置 hot 为 true,就会自动开启HMR功能(只能在开发模式下使用)

devServer: {
  //contentBase: resolve(__dirname, 'build'),
  compress: true,
  port: 3000,
  open: true,
  // 开启HMR功能
  // 当修改了webpack配置,新配置要想生效,必须重启webpack服务
  hot: true
}

每种文件实现热模块替换的情况:

  • 样式文件:可以使用HMR功能,因为开发环境下使用的 style-loader 内部默认实现了热模块替换功能

  • js 文件:默认不能使用HMR功能(修改一个 js 模块所有 js 模块都会刷新)

    --> 实现 HMR 需要修改 js 代码(添加支持 HMR 功能的代码)

    // 绑定
    if (module.hot) {
      // 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
      module.hot.accept('./print.js', function() {
        // 方法会监听 print.js 文件的变化,一旦发生变化,只有这个模块会重新打包构建,其他模块不会。
        // 会执行后面的回调函数
        print();
      });
    }
    

    注意:HMR 功能对 js 的处理,只能处理非入口 js 文件的其他文件。

  • html 文件: 默认不能使用 HMR 功能(html 不用做 HMR 功能,因为只有一个 html 文件,不需要再优化)

    使用 HMR 会导致问题:html 文件不能热更新了(不会自动打包构建)

    解决:修改 entry 入口,将 html 文件引入(这样 html 修改整体刷新)

    entry: ['./src/js/index.js', './src/index.html']
    

2 .source-map

source-map:一种提供源代码到构建后代码的映射的技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)

参数:[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

代码:

devtool: 'eval-source-map'

可选方案:[生成source-map的位置|给出的错误代码信息]

  • source-map:外部,错误代码准确信息 和 源代码的错误位置
  • inline-source-map:内联,只生成一个内联 source-map,错误代码准确信息 和 源代码的错误位置
  • hidden-source-map:外部,错误代码错误原因,但是没有错误位置(为了隐藏源代码),不能追踪源代码错误,只能提示到构建后代码的错误位置
  • eval-source-map:内联,每一个文件都生成对应的 source-map,都在 eval 中,错误代码准确信息 和 源代码的错误位
  • nosources-source-map:外部,错误代码准确信息,但是没有任何源代码信息(为了隐藏源代码)
  • cheap-source-map:外部,错误代码准确信息 和 源代码的错误位置,只能把错误精确到整行,忽略列
  • cheap-module-source-map:外部,错误代码准确信息 和 源代码的错误位置,module 会加入 loader 的 source-map

内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快

开发/生产环境可做的选择:

开发环境:需要考虑速度快,调试更友好

  • 速度快( eval > inline > cheap >... )
    1. eval-cheap-souce-map
    2. eval-source-map
  • 调试更友好
    1. souce-map
    2. cheap-module-souce-map
    3. cheap-souce-map

最终得出最好的两种方案 --> eval-source-map(完整度高,内联速度快) / eval-cheap-module-souce-map(错误提示忽略列但是包含其他信息,内联速度快)

生产环境:需要考虑源代码要不要隐藏,调试要不要更友好

  • 内联会让代码体积变大,所以在生产环境不用内联
  • 隐藏源代码
    1. nosources-source-map 全部隐藏
    2. hidden-source-map 只隐藏源代码,会提示构建后代码错误信息

最终得出最好的两种方案 --> source-map(最完整) / cheap-module-souce-map(错误提示一整行忽略列)

未完待续······

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值