webpack 学习笔记(下)

举报
阿童木 发表于 2021/08/22 14:55:40 2021/08/22
【摘要】 配置自动打包参数再次更改package.json文件中的dev属性"dev": "webpack server --open --host 127.0.0.1 --port 9999"--open是自动启动--host是指定地址--port是指定服务端口号也有另一种方法是通过修改webpack.config.js配置文件添加一个devServer属性,配置相关信息module.export...
配置自动打包参数

再次更改package.json文件中的dev属性

"dev": "webpack server --open --host 127.0.0.1 --port 9999"
  • --open是自动启动
  • --host是指定地址
  • --port是指定服务端口号

也有另一种方法是通过修改webpack.config.js配置文件

添加一个devServer属性,配置相关信息

module.exports = {
    ...
    output:{},
    devServer: {
        port: 3030,
        publicPath: './dist'
    },
}

webpack加载器和插件

这个真的超级常用,默认情况下,webpack只能打包js文件,如果想要打包非js文件,需要调用loader加载器才能打包

  • less-loader 可以打包处理 .less 相关的文件

  • sass-loader 可以打包处理 .scss 相关的文件

  • url-loader 可以打包处理 css 中与 url 路径相关的文件

loader调用过程

loader

注意:使用npm run dev是为了实时观看页面,但是不会生成文件,只是一个预览效果,所以我们要生成文件的时候需要使用webpack命令打包

1.打包处理css文件
  1. 安装loader包
npm install style-loader css-loader -D
  1. 在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下内容如下
output: {...},
module: {
    rules :[
        {
            test:/\.css$/,//匹配css文件,匹配成功使用下面的loader
            use:[
                'style-loader',
                'css-loader'
            ]
        }
    ]
},

注意

  • use 数组中指定的 loader 顺序是固定的
  • 多个 loader 的调用顺序是:从后往前调用
  • loader的摆放顺序出错可能会报错
2.打包处理less文件
  1. 打开终端,运行命令,下载less-loader
npm i less-loader less -D
  1. 添加配置文件,匹配less文件,使用loader加载
{
    test:/\.less$/,
    use:[
        'style-loader',
        'css-loader',
        'less-loader'
    ]
}

其实这部分理解了之后会很简单,上面这段代码我们可以接在处理css文件后面继续写,也就是可以理解为rules数组存放大量的规则,每个规则都是一个包含test和use的对象,这样就很清晰了

3.打包处理scss文件

这一部分内容我是没有成功的,查了很多资料都没有成功,视频课程讲解的webpack版本是4.x,我用的是5.x,有些东西被弃用了,安装==不成功==,所以可以跳过这部分

  1. 打开终端,运行命令,下包
npm i sass-loader node-sass -D
  1. 配置规则,继续在rules中添加配置
{
    test: /\.scss$/,
    use: ['style-loader',
        'css-loader',
        'sass-loader'
    ]
}
4.将css提取到单独文件
  1. 打开终端,运行命令
npm install --save-dev mini-css-extract-plugin
  1. 引入
//css提取成单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  1. 更改用户配置
//更改css相关配置
{
test: /\.css$/,
use: [
    //这里改以下
    MiniCssExtractPlugin.loader,
    'css-loader'
]
}
//创建插件对象
plugins: [
    htmlPlugin,
    new MiniCssExtractPlugin()
]
5.配置postCss自动添加css兼容性代码

这个是真的香

  1. 打开终端,运行命令,安装loader
npm install postcss-loader autoprefixer -D
  1. 在项目根目录创建并配置postcss.config.js文件
const autoprefixer = require("autoprefixer");//引入
module.exports = {
    plugins:[ autoprefixer ]
}
  1. 配置规则,更改rules数组
//更改css相关配置
{
test: /\.css$/,
use: [
    MiniCssExtractPlugin.loader,
    'css-loader',
    //在这里添加新的loader规则
    'postcss-loader'
]
}
6.开启CSS压缩

webpack4使用optimize-css-assets-webpack-plugin插件,方法和上面的都一样,引入,然后创建实例对象

下面记录webpack5的使用

  1. 打开终端,安装插件
npm install css-minimizer-webpack-plugin --save-dev
  1. 引入创建插件对象
//引入
const CSSMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
...
//在plugins数组中创建
plugins: [
    htmlPlugin,
    new MiniCssExtractPlugin(),
    new CSSMinimizerWebpackPlugin()
]
7.打包样式表中的图片

在样式表css中有时候会设置背景图片和设置字体文件,一样需要loader进行处理
使用url-loader和file-loader来处理打包图片文件以及字体文件

  1. 打开终端,安装loader
npm install url-loader file-loader -D
  1. 配置loader文件
{
    test:/\.(jpg|png|gif|bmp|ttf|eot|svg|woff|woff2)$/,
    use:"url-loader?limit= 8 * 1024"
}

注意

  1. css样式表中的文件才会通过这个插件被打包
  2. ?limit后面填的是字节大小,只有小于这个数的才会被直接打包,存放的是你自己写的那个路径,大于这个数,会转化为base64路径
8.打包其他文件

在上一步中已经安装好了loader,添加配置文件即可

{
    exclude:/\.(css|js|html|less|jpg|png|gif|bmp|ttf|eot|svg|woff|woff2)$/,//排除这些文件
    loader:'file-loader',
    options: {
        name: '[hash:10].[ext]'//缩短文件名
    }
}
9.打包js文件的高级语法
  1. 打开终端,安装babel
npm install babel-loader @babel/core @babel/runtime -D
  1. 安装babel语法插件包
npm install @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
  1. 在项目根目录创建并配置babel.config.js文件
module.exports = {
        presets:["@babel/preset-env"],
        plugins:[ "@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties" ]
}
  1. 更改用户配置文件中的rules,数组下继续添加
{
    test:/\.js$/,
    use:"babel-loader",
    //use表示该文件类型需要调用的loader
    exclude:/node_modules/
}
10.文件输出到相应文件夹

css文件

在实例化的时候添加参数配置

new MiniCssExtractPlugin({
     filename: 'css/[name].css'
})

图片文件

在rules中添加options配置内容

{
    test: /\.(jpg|png|gif|bmp|ttf|eot|svg|woff|woff2)$/,
    use: [{
        loader: "url-loader",
        options: {
            limit: 8 * 1024,
            name: '[hash:10].[ext]',
            esModule: false,
            outputPath: './imgs',
            publicPath: './imgs' // 开发环境配置
        }
    }]
}
11.压缩html代码

和上面一样添加插件配置

其实就是配置删除空格和注释

//
const htmlPlugin = new HtmlWebpackPlugin({
    //设置生成预览页面的模板文件
    template: "./src/index.html",
    //设置生成的预览页面名称
    filename: "index.html",
    //添加压缩代码
    collapseWhitespace: true,
	removeComments: true,
    options: {
        esModule: false
    }
})

完整配置

const path = require('path'); //导入node.js中操作路径的模块
//导入html包
const HtmlWebpackPlugin = require("html-webpack-plugin");
//创建对象
const htmlPlugin = new HtmlWebpackPlugin({
    //设置生成预览页面的模板文件
    template: "./src/index.html",
    //设置生成的预览页面名称
    filename: "index.html",
    //压缩代码
    // collapseWhitespace:true,
    // removeComments:true,
    options: {
        esModule: false
    }
})
//css提取成单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//css压缩
const CSSMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
    entry: path.join(__dirname, "./src/js/index.js"), //设置入口文件路径
    //配置出口文件
    output: {
        path: path.join(__dirname, "./dist"), //设置路径
        filename: "js/bundle.js" //设置导出文件名
    },
    module: {
        rules: [{
            //处理css
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            },
            {
                //处理less
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            },
            {
                //处理scss,不用
                test: /\.scss$/,
                use: ['style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            },
            {
                //处理图片
                test: /\.(jpg|png|gif|bmp|ttf|eot|svg|woff|woff2)$/,
                use: [{
                    loader: "url-loader",
                    options: {
                        limit: 8 * 1024,
                        name: '[hash:10].[ext]',
                        esModule: false,
                        outputPath: './imgs',
                        publicPath: '../imgs' // 公共路径
                    }
                }]

            },
            {
                //处理其他资源
                exclude: /\.(css|js|html|less|jpg|png|gif|bmp|ttf|eot|svg|woff|woff2)$/,
                loader: 'file-loader',
                options: {
                    name: '[hash:10].[ext]',
                    outputPath: 'media',
                    publicPath: '../media' // 开发配置或者就行
                }
            },
            {
                //转化高级js代码
                test: /\.js$/,
                use: "babel-loader",
                exclude: /node_modules/
            }
        ]
    },
    devServer: {
        //服务器相关配置
        port: 9999,
        open: true
    },
    target: 'web',//实时刷新
    devtool: "eval-source-map", //后面会写到
    plugins: [
        htmlPlugin,
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        }),
        new CSSMinimizerWebpackPlugin()
    ],
    //模式选择
    mode: "development"
}

性能优化配置

使用HMR优化打包构建速度

HMR对html,css,js都有不同的配置,js,和html文件默认是不使用HMR功能的

问题:如果我们只是修改了样式文件,没有被修改过的js等文件也会因为页面的刷新而被重新加载一次,所有的代码被重新执行一次即,这种情况往往不是我们想要的效果

解决方法:使用HMR功能来完成这个需求。它的作用是当一个模块发生变化,只会重新打包这一个模块,而不是打包加载所有模块`,极大提升构建速度

devServer: {
  port: 9999,
  open: true,
  // 开启HMR功能
  // 新配置要想生效,必须重新webpack服务
  // 重新执行npx webpack server指令
  hot: true
}
  • HMR功能开启后当我们修改样式文件,我们在控制台上可以发现此时只有该样式文件被重新加载刷新了,其他的文件不会重新输出。

注意

  1. 对于html文件不需要做HMR功能,因为只有一个html文件,只要修改了,必定重新加载
  2. js文件用HMR感觉不太友好
if (module.hot) {
  // 一旦 module.hot 为true,说明开启了HMR功能。 
  // 额外添加下面的JS代码
  // 让HMR功能代码在此JS文件修改时生效
  module.hot.accept('./print.js', function() {
    // 方法会监听 print.js 文件的变化
    // 一旦发生变化,其他模块不会重新打包构建。
    // 会执行后面的回调函数
    print();//这是一个js文件下的函数
  });
}

使用HMR优化打包构建速度

使用source-map优化代码调试

  • source-map是一种提供源代码到构建后代码映射技术,简单来说就是配置文件报错的提示方式,在配置文件中配置devtool即可
devServer: {},
target: 'web',//实时刷新
devtool: "eval-source-map"

直接配置在export对象下

对于devtool配置有两种方案,内联和外联

  • 内联和外部的区别
    1. 外联生成了文件,内联不生成
    2. 内联构建速度更快,但是文件体积会更大

这里的配置选项相当多,可以直接查看devtool

开发环境

  • 需要考虑速度快,调试更友好
速度快(eval>inline>cheap>…) eval-cheap-souce-map和eval-source-map
调试更友好 souce-map和cheap-module-souce-map和cheap-souce-map

推荐使用:eval-source-map() / eval-cheap-module-source-map

生产环境

  • 内联会让代码体积变大,所以在生产环境不用内联
source-map 能够提供错误代码准确信息和源代码的错误位置
cheap-module-souce-map 能够提供错误代码准确信息和源代码的错误位置只能精确的行而不是列
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息

推荐使用:source-map(

使用oneOf优化打包构建速度

在我们之前写的rules中,每一个文件都会被所有的规则判断一遍,这样的操作是没有必要的

因此我们使用oneOf来解决这个问题,优化我们的打包代码

在所有的rules外层用一个oneof数组包裹,也就是将我们之前写的规则放在oneof数组中,oneof数组放在rules数组对象中

rules: [
	{
		oneOf:[...相关loader]
	}
]

如果有需要匹配两次以上的,需要将对应的loader放在外部,和oneOf数组存在的对象同级,可以通过添加enforce: 'pre'属性,优先执行这个规则


长长的分割线

到这里其实后面还有很多的优化没有写,但是真的有点枯燥,很多人说利用vue脚手架,能很轻松的解决掉了,所以我想webpack学习就先到这里吧,已经花费了太多的时间了,需要学习一些其他的东西,或者做一些demo来练习以下了!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。