likes
comments
collection
share

webpack5-plugin-dev-server

作者站长头像
站长
· 阅读数 21

webpack5-plugin

一、认识plugin

loader: 转换 特定类型 读取文件时
plugin: 可做更多的事情,在打包的流程中,穿插一些操作(清理原有打包结果、css压缩、创建html模板、定义项目全局变量等)

使用一个常见的plugin(分内置与第三方),清理原有打包结果:clean-webpack-plugin下载:

yarn -D add clean-webpack-plugin

在webpack.config.js中配置plugins:

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
   ...
   plugins: [
      new CleanWebpackPlugin()
   ]
}

/**
 * 插件就是一个类,类似于:
 * class HelloPlugin {
 *   contructor(){}
 *   apply(compiler) {}
 * }
 * 需要使用模块化的方式引入,然后使用new关键字创建对象,再放入plugins数组中
 */

二、常用插件使用

1.html-webpack-plugin使用

功能:

用于生成html模板文件

安装:

yarn -D add html-webpack-plugin        

配置插件:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const { DefinePlugin } = require('webpack');    //用于定义项目全局常量


plugins: [
      ...
        new HtmlWebpackPlugin({
         title: 'html-webpack-plugin',
         template: './public/index.html',
      }),
      new DefinePlugin({
         BASE_URL: '"./"'
      })
   ]

// 将来webpack定义常量时,会直接 const BASE_URL = ./ ,会有语法错误,需要写成 const BASE_URL = '"./"'

2.Babel使用

a.命令行中使用babel

为什么需要 Babel?

 JSX TS ES6+ ---> 浏览器平台直接使用(配合.browserslistrc条件)
  转换
 Babel 类似于 postcss ,自身没有功能,只是为了转换提供平台
 处理 JS 兼容

常用工具包:

  转换箭头函数:@babel/plugin-transform-arrow-functions
  转换变量声明:@babel/plugin-transform-block-scoping
  包含多种转换:@babel/preset-env

安装babel相关包:

yarn -D add @babel/core        // 转换js的核心包(微内核),如果需要在转换过程中修改代码,该需要配合其它插件
yarn -D add @babel/cli        // 为了能在命令行中直接使用babel

命令行中使用babel:

 npx babel src --out-dir build
            //文件或目录(编译该目录下所有js)   输出路径

转换箭头函数:

// 安装依赖包     yarn -D add @babel/plugin-transform-arrow-functions
// 命令行中使用    npx babel src --out-dir build --plugins=@babel/plugin-transform-arrow-functions

转换变量声明方式(let、const ==> var):

// 安装依赖包     yarn -D add @babel/plugin-transform-block-scoping
// 命令行中使用    npx babel src --out-dir build --plugins=@babel/plugin-transform-arrow-functions,@babel/plugin-transform-block-scoping

使用预设依赖包(包含了较多新语法的转换方式):

// 安装依赖包     yarn -D add @babel/preset-env
// 命令行中使用    npx babel src --out-dir build --presets=@babel/preset-env
b.在webpack中配置babel

可以在webpack配置文件中,或.browserslistrc文件配置浏览器筛选条件安装babel-loader

yarn -D add babel-loader

配置处理js文件:

{
    test: /\.js$/,
    use: [
       {
          loader: 'babel-loader',
          options: {
             // 使用单个工具包聚合
             // plugins:[
             //    '@babel/plugin-transform-arrow-functions',
             //    '@babel/plugin-transform-block-scoping'
             // ]

// 使用babel预设工具包
             presets: ['@babel/preset-env']
             // presets: [
             //    [
             //       '@babel/preset-env',
             //       { targets: 'chrome 91' }
             //    ]
             // ]
          }
       }
    ],

 }

使用babel.config.js配置文件:

module.exports = {
    presets: ['@babel/preset-env']
}


/**
 * babel-loader 相关配置文件
 *      babel.config.js(json cjs mjs)   现在是多包风格,建议使用
 *      bebelrc.json(js)    babel 7.x之前使用的较多
 * 
 */

使用配置文件后配置babel-loader时:

 {
    test: /\.js$/,
    use: ['babel-loader'],
 }

3.polyfill的使用

功能:

polyfill 是什么?    实行打补丁的操作
旧浏览器提供它没有原生支持的较新的功能。 用原生js实现的新的语法、新的接口、新的功能的代码块。

简述:webpack5-plugin-dev-server

安装依赖:

yarn add core-js regenerator-runtime

在main.js中引入依赖:

import 'core-js/stable';
import 'regenerator-runtime/runtime';

使用polyfill后的babel-loader的配置:

   {
    test: /\.js$/,
    exclude: /node_modules/, // 排除掉node_modules目录下的js文件,避免重复填充处理
    use: ['babel-loader'],
 }

使用polyfill后的babel.config.js的配置:

module.exports = {
    // 并不能完成所有功能的转换
    presets: [
        [
            '@babel/preset-env',
            {
                // false:不对当前的的JS处理做 polyfill 的填充
                // 'usage':依据用户源代码中所使用到的新语法进行填充
                // 'entry':根据需要兼容的浏览器进行填充
                useBuiltIns:'entry',
                corejs:3    // 指定使用的核心js版本
            }
        ],
        
    ]  

}

4.copy-webpack-plugin使用

功能:

部分资源文件不需要打包,只需要复制到指定目录之下

安装:

yarn -D add copy-webpack-plugin

使用copy-webpack-plugin插件时的配置:

const CopyWebpackPlugin = require('copy-webpack-plugin');

new CopyWebpackPlugin({
     patterns: [
        // {
        //    from: path.resolve(__dirname, 'public/favicon.ico'),
        //    // to: path.resolve(__dirname, 'dist/favicon.ico'), // 拷贝到dist目录下,默认会自动拷贝到output目录下
        // }
        {
           from:'public',
           // to:'dist', 默认到output目录下
           globOptions: {
              ignore: ['**/index.html'] // 忽略掉该目录下的index.html文件
           }
        }
     ]
  })

4.webpack-dev-server使用

检测源代码变化,并重新打包:

// 打包时 添加 --watch参数
  "scripts": {
    "build": "webpack --watch"
  },

配置到webpack.config.js中检测变化:

module.exports = {
   watch:true,
    ...
}

缺点:

/**
 * 开发模式
 *  -   watch: true或者webpack -- watch
 *  -   live server
 * 
 * 不足:
 *  1.修改后,所有源代码都会重新编译
 *  2.每次编译成功之后都需要进行文件读写
 *  3.live server 是vscode的插件
 *  4.不能实现局部更新
 * 
 * 
 * 使用webpack-dev-server
 */

使用webpack-dev-server:安装:

yarn add -D webpack-dev-server

使用打包并开启服务:

webpack serve

webpack-dev-middleware使用,其内部使用了webpack-dev-server:

流程:webpack5-plugin-dev-server安装

yarn -D add express wabpack-dev-middleware

    express 开启本地服务器
    middleware 将打包之后的结果,交给本地服务器

使用middle,配合express:

const express = require('express');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');


const app = express();

// 获取配置文件
const config = require('./webpack.config.js');
const compiler = webpack(config);


app.use(webpackDevMiddleware(compiler,{
    publicPath: config.output.publicPath
}));

// 开启端口上的服务
app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
})

5.HMR功能使用

模块热替换(hot module replacement),需要配合webpack-dev-server使用

开发阶段屏蔽掉.browerslistrc的影响:



module.exports = {
   mode: 'development',
   devtool: false,
   entry: './src/main.js',
   output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'bundle.js',
      // publicPath: '/dist/',
   },
   target: 'web', // 开发阶段屏蔽.browserslistrc
   devServer: {
      hot: true,    // 开启HMR功能的
   }
}

开启HMR功能后,默认情况下,还是刷新整个页面,需要再代码中,手动设置:

import 'core-js/stable';
import 'regenerator-runtime/runtime';
import './title'

console.log('--main.js is running');  // 这里不会更新

if(module.hot){
    // 判断是否开启热更新
    module.hot.accept(['./title.js'],()=>{ // 填写需要热更新的文件
        console.log('title.js更新了'); 
    }); 
}

6.框架热更新实现

a.React_HMR

使用@babel/preset-react解析jsx文件安装:

yarn add -D @babel/preset-react


// babel-loader配置:
 {
    test: /\.jsx?$/,
    exclude: /node_modules/, // 排除掉node_modules目录下的js文件,避免重复填充处理
    use: ['babel-loader'],
 }

// babel.config.js配置
module.exports = {
    presets: [
        ['@babel/preset-env'],
        ['@babel/preset-react'], 
    ]  
}

使用 @pmmmwh/react-refresh-webpack-plugin与react-refresh实现React的HMR:安装:

yarn add -D @pmmmwh/react-refresh-webpack-plugin react-refresh

@pmmmwh/react-refresh-webpack-plugin // 该插件的功能是让webpack与react-refresh插件结合
react-refresh 实现react的局部组件更新

配置:

// webpack.config.js
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')



module.exports = {
   mode: 'development',
   ...
   target: 'web', // 开发阶段屏蔽.browserslistrc
   devServer: {
      hot: true,
   },
   ...
   plugins: [
      ...
      new ReactRefreshWebpackPlugin(),
   ]
}


// 在babel.config.js中配置实现react的HMR的插件
module.exports = {
    presets: [
        ['@babel/preset-env'],
        ['@babel/preset-react'], 
    ],
    plugins: [
        ['react-refresh/babel'],
    ]
}
b.Vue_HMR

安装vue-template-compiler(2.6)、vue-loader(15)让起能编译 .vue (vue2)文件:

yarn add -D vue-template-compiler@2.6 vue@2.6 vue-loader@15

配置vue-loader:

const VueLoderPlugin = require('vue-loader/lib/plugin'); // 在15版本之前则不需要引入vue-loader插件


module.exports = {
   mode: 'development',
   ...
   target: 'web', // 开发阶段屏蔽.browserslistrc
   devServer: {
      hot: true,
   },
   module: {
      rules: [
         ...
         {
            test: /\.vue$/,
            use: ['vue-loader']
         }
      ]
   },
   plugins: [
      ...
      new VueLoderPlugin()
   ]
}

使用vue-loader后,vue默认支持hmr

转载自:https://segmentfault.com/a/1190000041810154
评论
请登录