一天搞定前端必备开发技能(4)—— Webpack最热门构建工具

模块化介绍

模块化是指把⼀个复杂的系统分解到多个模块以⽅便编码。

CommonJS

CommonJS 是⼀种使⽤⼴泛的 JavaScript 模块化规范,核⼼思想是通过 require ⽅法来同步地加载依赖的其他模块,通过 module.exports 导出需要暴露的接⼝。 CommonJS 规范的流⾏得益于 Node.js 采⽤了这种⽅式,后来这种⽅式被引⼊到了⽹⻚开发中。

采⽤ CommonJS 导⼊及导出时的代码如下:

// 导⼊
const moduleA = require('./moduleA');
// 导出
module.exports = moduleA.someFunc;

AMD

AMD 也是⼀种 JavaScript 模块化规范,与 CommonJS 最⼤的不同在于它采⽤异步的⽅式去加载依赖的模块。 AMD 规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是 requirejs。

采⽤ AMD 导⼊及导出时的代码如下:

// 定义⼀个模块
    define('module', ['dep'], function(dep) {
    	return exports;
    });
// 导⼊和使⽤
    require(['module'], function(module) { });

ES6模块化

ES6 模块化它在语⾔的层⾯上实现了模块化。浏览器⼚商和 Node.js 都宣布要原⽣⽀持该规范。它将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通⽤的模块解决⽅案。

采⽤ ES6 模块化导⼊及导出时的代码如下:

// 导⼊
    import { readFile } from 'fs';
    import React from 'react';
// 导出
    export function hello() {};
    export default {
    	// ...
    };

ES6模块虽然是终极模块化⽅案,但它的缺点在于⽬前⽆法直接运⾏在⼤部分 JavaScript 运⾏环境下,必须通过⼯具转换成标准的 ES5 后才能正常运⾏。

样式文件中的模块化

除了 JavaScript 开始模块化改造,前端开发⾥的样式⽂件也⽀持模块化。 以 SCSS 为例,把⼀些常⽤的样式⽚段放进⼀个通⽤的⽂件⾥,再在另⼀个⽂件⾥通过 @import 语句去导⼊和使⽤这些样式⽚段。

新框架

  • React 框架引⼊ JSX 语法到 JavaScript 语⾔层⾯中,以更灵活地控制视图的渲染逻辑。
  • Vue 框架把⼀个组件相关的 HTML 模版、JavaScript 逻辑代码、CSS 样式代码都写在⼀个⽂件⾥,这⾮常直观。

Webpack初步

随着Web应用的日益复杂化,相关开发技术如同春日里的百花争艳,竞相绽放。这一趋势对前端构建工具提出了更为严苛的要求。在众多构建工具中,Webpack以其卓越的性能和灵活性脱颖而出,成为当前最为流行且不可或缺的前端构建工具之一。它几乎已经成为每一位追求前沿技术的前端工程师必备的技能之一。因此,紧跟行业步伐的前端工程师们,掌握Webpack已成为提升工作效率、优化项目开发的必修课。

Webpack环境配置

  1. 安装到全局

    npm i -g webpack
    npm i -g webpack-cli
    
  2. 查看版本

    webpack -v
    
  3. 安装依赖
    这一步需要我们打开我们的vscode,打开我们的项目里的终端,输入以下👇命令:

    npm init
    

    然后就会出现一个package.json描述文件

  4. 安装webpack到项目当中

    npm i -D webpack 
    npm i -D webpack-cli
    
  5. 使用Webapck

    1. 创建一个public文件夹,主要放置主入口文件

    2. 再创建一个webpack.config.js文件

    3. webpack.config.js文件书写代码

      const path = require("path");
      module.exports={
      	//入口
      	entry:"引用文件路径",
      	//把所有依赖的模块合并并输出到一个"输出文件的文件名.格式"文件中
      	output:{
      		filename:"输出文件的文件名.格式",
      		path:path.resolve(__dirname,"输出路径"),
      	}
      }
      
  6. 运行Webpack进行打包,只需要在终端输入webpack即可运行。

  7. 在入口文件index.html引入输出的打包文件,就可以查看运行效果。

使用Loader

Loader是一个重要点,是webpack的核心概念之一。我们在使用webpack一定要知道一切皆模块。那么所有的内容都必须要经过webpack进行处理,不过是图片还是CSS文件,并不是随便引入就能直接运行的。

如果要支持非JS类型的键,需要使用Webpack的Loader机制。Webpack的配置修改使用如下:(我们这里已添加Css文件为例)

  1. 安装CSS依赖

    npm i -D style-loader css-loader
    
  2. 修改webpack.config.js配置文件

    module:{
        //配置很多你需要处理的方案
        rules:[
            {
                //test:⽤正则去匹配要⽤该转换的 CSS ⽂件
                test: /\.css$/,
                //使用Loader插件进行处理
                use:["style-loader","css-loader"]
            }
        ]
    }
    

配置一个webpack快捷启动方案:

打开package.json

image-20240715160115676

然后输入

"起一个看名字"="webpack"

image-20240715161123865

使用plugin

Plugin 是⽤来扩展 Webpack 功能的,是Webpack的核心特性之一,它们被用来扩展Webpack的功能。Webpack自身只负责打包模块,而插件则可以用来处理各种各样的任务,从打包优化和资源管理到环境变量注入等。

  1. 安装插件:首先,需要通过npm或yarn来安装所需的插件。

    npm install --save-dev plugin-name
    
  2. 配置插件:在webpack.config.js文件中,通过在plugins数组中添加一个新的插件实例来配置插件。

    const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入插件
    module.exports = {
      // ...其他配置...
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html' // 插件配置
        }),
        // ...其他插件...
      ],
    };
    
  3. 运行Webpack:配置完成后,运行Webpack进行构建,插件就会在构建过程中执行其功能。

下面我简单举两个常用的插件进行讲解。

分离css和js插件

  1. 安装插件依赖
npm install --save-dev optimize-css-assets-webpack-plugin
npm install --save-dev mini-css-extract-plugin
  1. 配置加载文件

    在上⼀节中通过 Loader 加载了 CSS ⽂件,本节将通过 Plugin 把注⼊到 bundle.js ⽂件⾥的 CSS 提取到单独的

    ⽂件中,配置修改如下:

    const path = require('path');
    // 压缩CSS代码
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    // 分离CSS代码
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
      // JavaScript 执行入口文件
      entry: './src/index.js',
      output: {
        // 把所有依赖的模块合并输出到一个 bundle.js 文件
        filename: 'bundle.js',
        // 输出文件都放到 dist 目录下
        path: path.resolve(__dirname, './dist'),
      },
      module: {
        rules: [
          {
            // 用正则去匹配要用该 loader 转换的 CSS 文件
            test: /\.css$/,
            use: [
              {
                loader: MiniCssExtractPlugin.loader,
              },
              "css-loader",
            ],
          },
        ],
      },
      plugins: [
        // css代码压缩
        new OptimizeCssAssetsPlugin(),
        // 单独提取CSS文件
        new MiniCssExtractPlugin({
          filename: "main.css",
          chunkFilename: "[id].css",
        }),
      ],
    };
    
    

分离html文件插件

经过了上面的文件分离,此时我们的⽂件是放⼊在dist⽂件夹中,但是dist本事是动态⽣成的⽣产环境,所以。我们此时创建public⽂件夹,然后配置HTML⽂件分离。

  1. 安装依赖
    创建public⽂件夹,然后移动index.html到public⽂件夹中

    npm install -D html-webpack-plugin
    
  2. 修改配置⽂件

    const HTMLPlugin = require('html-webpack-plugin')
        plugins: [
             new HTMLPlugin({
             template: './public/index.html'
         })
    ]
    

使用DevServer

前⾯的⼏节只是让 Webpack 正常运⾏起来了,但在实际开发中你可能会需要在服务器运行,所以本节就来讲解如何在服务器端进行运行。

  1. 安装一个依赖

    npm install -D webpack-dev-server
    
  2. 增加一些关于服务器的配置

    devServer:{
        //服务器打开目录
        contentBase:path.join(__dirname,"默认打开的文件夹名称")
        //是否需要压缩
        compress:true,
        port:8080,	//选择端口号
        hot:ture,	//是否热更新,就是对代码的修改会进行监听,会自动更新浏览器
        open:true	//自动打开浏览器
    }
    
  3. 修改package.json文件

    "dev": "webpack-dev-server --config webpack.config.js"
    
  4. 运行命令

    npm run dev
    

配置一个运行命令快捷执行方式:

同样的打开package.json

image-20240715163242061

最后输出的命令就不一样了🥳

image-20240715163302849

更多配置

通过前面的学习,我们已经对Webpack有了初步的认识,虽然Webpack功能强大、内容复杂,但是只要你理解了其中的几个核心概念,就能得心应手的使用它。

下面来介绍以下Webpack的几个核心概念:

  • Entry:⼊⼝,Webpack 执⾏构建的第⼀步将从 Entry 开始,可抽象成输⼊。
  • Module:模块,在 Webpack ⾥⼀切皆模块,⼀个模块对应着⼀个⽂件。Webpack 会从配置的 Entry 开
  • 始递归找出所有依赖的模块。
  • Chunk:代码块,⼀个 Chunk 由多个模块组合⽽成,⽤于代码合并与分割。
  • Loader:模块转换器,⽤于把模块原内容按照需求转换成新内容。
  • Plugin:扩展插件,在 Webpack 构建流程中的特定时机注⼊扩展逻辑来改变构建结果或做你想要的事
  • 情。
  • Output:输出结果,在 Webpack 经过⼀系列处理并得出最终想要的代码后输出结果。

entry配置

entry是配置模块的⼊⼝,可抽象成输⼊,Webpack 执⾏构建的第⼀步将从⼊⼝开始搜寻及递归解析出所有⼊⼝依赖的模块。

  • entry 配置是必填的,若不填则将导致 Webpack 报错退出。

例如,在⼀个项⽬中,可以存在多个⼊⼝地址,此时可以在entry中配置。增加其他⼊⼝⽂件dist/login.html和src/login/login.js

image-20240715163501638

修改输出文件image-20240715163536566

entry: {
     index: "./src/index.js",
     login: "./src/login/login.js"
 },
 // 模式区分:⽣产和开发环境
 mode: 'development',
 output: {
     // 把所有依赖的模块合并输出到⼀个 bundle.js ⽂件
     	filename: '[name].js',
     // 输出⽂件都放到 dist ⽬录下
     	path: path.resolve(__dirname, './dist'),
 }

运⾏代码之后,我们可以访问两个⼊⼝,在login的路径中可以看到打印:

http://localhost:9000
http://localhost:9000/login

Resolve配置

Webpack 在启动后会从配置的⼊⼝模块出发找出所有依赖的模块,Resolve 配置 Webpack 如何寻找模块所对应的⽂件。 Webpack 内置 JavaScript 模块化语法解析功能,默认会采⽤模块化标准⾥约定好的规则去寻找,但你也可以根据⾃⼰的需要修改默认的规则。

resolve下⾯有很多配置,我们这⾥介绍⼀个简单的,取消添加后缀:

resolve: {
 	extensions: ['.js', '.json']
},

Vue环境配置

Vue 是一个灵活轻量的MVVM框架,与React和Angular相比,它提供了渐进式的功能集成。Vue不强加特定的功能和语法,允许开发者根据项目需求逐步添加所需功能。尽管Vue项目可以直接在浏览器环境中运行,但为了提高编码效率,大多数项目都倾向于使用Vue官方推荐的单文件组件(.vue文件)格式进行开发。本书将重点介绍如何利用Webpack来构建Vue单文件组件,而不是传统的直接引用Vue的方式,后者虽然经典但已较为过时。

  1. 接下来我们配置⼀下相关环境 css预处理器

    npm i -D stylus stylus-loader
    npm i -D postcss-loader
    
    1. 预处理器⼯具

      npm i -D autoprefixer
      
    2. 处理html⽂件

      npm i -D html-webpack-plugin
      
    3. 处理vue⽂件

      npm i -D vue vue-loader vue-style-loader vue-template-loader vue-templatecompiler
      
  2. 修改webpack.config.js⽂件

    const path = require('path');
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const VueLoaderPlugin = require('vue-loader/lib/plugin');
    const HTMLPlugin = require('html-webpack-plugin');
    const webpack = require('webpack');
    
    module.exports = {
      // JavaScript 执行入口文件
      entry: {
        index: "./src/index.js",
        login: "./src/login/login.js",
      },
      // 模式区分:生产和开发环境
      mode: 'development',
      output: {
        // 把所有依赖的模块合并输出到一个 [name].js 文件
        filename: '[name].js',
        // 输出文件都放到 dist 目录下
        path: path.resolve(__dirname, './dist'),
      },
      module: {
        rules: [
          {
            // 用正则去匹配要用该 loader 转换的 CSS 文件
            test: /\.css$/,
            use: [
              {
                loader: MiniCssExtractPlugin.loader,
              },
              "css-loader",
            ],
          },
          {
            test: /\.js$/,
            use: ['babel-loader'],
            include: path.resolve(__dirname, 'src'),
          },
          {
            test: /\.vue$/,
            use: {
              loader: 'vue-loader',
            },
          },
          {
            test: /\.styl/,
            use: [
              'style-loader',
              'css-loader',
              'postcss-loader',
              'stylus-loader',
            ],
          },
        ],
      },
      plugins: [
        // css代码压缩
        new OptimizeCssAssetsPlugin(),
        // 单独提取CSS文件
        new MiniCssExtractPlugin({
          filename: "main.css",
          chunkFilename: "[id].css",
        }),
        new VueLoaderPlugin(),
        new HTMLPlugin({
          filename: './public/index.html',
          template: './public/index.html',
        }),
        new webpack.HotModuleReplacementPlugin(),
      ],
      devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 9000,
        hot: true,
        open: true,
      },
      resolve: {
        extensions: ['.js', '.json'],
      },
    };
    
    
  3. 修改主⼊⼝⽂件index.js如下

    import "../assets/css/main.css"
    import Vue from 'vue';
    import App from './components/hello.vue'; 
    new Vue({ 
         el: '#root', 
         render: h => h(App)
    });
    
  4. 复制index.html⼊⼝⽂件到public/index.html

  5. 同时需要处理css,在项⽬根⽬录下创建postcss.config.js

    const autoprefixer = require('autoprefixer')
    module.exports = {
         plugins:[
         	autoprefixer()
         ]
    }
    

React框架配置

接下来我们构建⼀个React基础环境,在React中我们需要解决的jsx语法问题。

  1. 安装依赖

    npm install -D @babel/preset-react
    npm install -S react
    npm install -S react-dom
    
  2. 在配置⽂件中,我们也需要添加jsx语法的解析

    {
    	//⼀个匹配loaders所处理的⽂件的拓展名的正则表达式,这⾥⽤来匹配js和jsx⽂件(必须)
         test: /\.(js|jsx)$/,
        //屏蔽不需要处理的⽂件(⽂件夹)(可选)
         exclude: /node_modules/,
         //loader的名称(必须)
         loader: 'babel-loader',
    }
    
  3. 同时我们需要修改.babelrc⽂件

    {
         "presets": [
             [
                 "@babel/preset-env",
                     {
                     "modules": false,
                     "targets": {
                         "browsers": [
                             "> 1%",
                             "last 2 versions",
                             "not ie <= 8"
                         ]
                     }
                 }
             ],
             "@babel/preset-react"
         ]
    }
    
  4. 修改主⽂件,键⼊React代码

    import React from 'react'
    import ReactDom from 'react-dom'
    class App extends React.Component {
         render(){
             return (
                 <div style={{color:"#333"}}>
                 	Hello
                 </div>
             )
         }
    }
    ReactDom.render(<App/>,document.getElementById("root"))
    

加载图片

在⽹⻚中不可避免的会依赖图⽚资源,在Webpack中加载图片通常涉及到使用file-loaderurl-loader

  1. 安装依赖

    npm install --save-dev file-loader url-loader
    
  2. 修改配置

    {
         test: /\.(png|jpe?g|gif)$/i,
             use: [
                 {
                 	loader: 'file-loader',
                 },
         ],
    },
    
  3. 使用图片
    在你的JavaScript或CSS文件中,你可以通过以下方式引入图片:

    import img from './path/to/image.png';
    
    // 在JavaScript中使用
    document.getElementById('image').src = img;
    
    // 在CSS中使用
    .image {
      background-image: url('./path/to/image.png');
    }
    
    

Webpack优化

webpack的优化有非常非常多内容,虽然内容都非常的多,我们也只需了解即可,到企业真正用到了的时候再去查看webpack文档即可。下面我通过ai输出了一些关于webpack优化的常用手段,大家可以看一看💪⛽️。

Webpack优化可以从多个方面进行,以提高构建速度、减少最终bundle的大小、改善开发体验和运行性能。以下是一些常用的Webpack优化策略:

优化构建速度

使用webpack-dashboard

webpack-dashboard提供了一个更友好的Webpack输出界面,同时也有助于提高构建速度。

缩小文件搜索范围

  • 使用resolve.extensions减少解析文件时的后缀尝试。
  • 使用resolve.alias为常用模块创建别名。
  • 使用module.noParse避免解析那些没有模块化的库。

利用缓存

  • 使用cache-loader或开启其他loader的缓存功能。
  • 使用HardSourceWebpackPlugin为模块提供中间缓存。

多线程/多实例构建

  • 使用thread-loaderparallel-webpack

开启监听模式时优化

  • 使用watchOptions来减少文件监听的开销。

优化输出文件

分割代码

  • 使用SplitChunksPlugin来分割代码块。
  • 使用动态导入(如import())实现懒加载。

压缩代码

  • 使用TerserPlugin压缩JavaScript。
  • 使用css-minimizer-webpack-plugin压缩CSS。

移除无用的代码

  • 使用Tree Shaking去除未引用的代码。
  • 使用_PURGE_变量和_PURGE_|webpackChunkName注释来清除未使用的样式。

图片优化

  • 使用image-webpack-loader压缩图片。

优化运行性能

使用Preload/Prefetch

  • 使用魔法注释/* webpackPrefetch: true *//* webpackPreload: true */来优化资源加载顺序。

使用CDN和缓存

  • output.publicPath中使用CDN地址。
  • 设置合适的缓存策略。

优化开发体验

使用Source Maps

  • 配置devtool选项生成source maps。

热替换(HMR)

  • 使用webpack-dev-server的HMR功能。

开发和生产环境的区分

  • 使用环境变量和不同的配置文件(如webpack.common.js, webpack.dev.js, webpack.prod.js)。

其他优化

使用webpack-bundle-analyzer

  • 分析bundle内容,找出优化的机会。

使用speed-measure-webpack-plugin

  • 测量Webpack构建过程中各个阶段的时间。

使用webpackbar

  • 显示构建进度条。

示例配置

以下是一个简单的Webpack优化配置示例:

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
  // ...
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
      }),
      new OptimizeCSSAssetsPlugin({}),
    ],
    splitChunks: {
      chunks: 'all',
    },
  },
  plugins: [
    new CleanWebpackPlugin(),
    // 其他插件...
  ],
  // ...
};

以上仅列举了一些常见的Webpack优化策略,实际项目中可能需要根据具体情况选择合适的优化方法。

(以上👆webpack优化内容由ai输出,仅供参考)

  • 28
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值