了解webpack

363 阅读6分钟

模块化的相关规范

  • 传统开发模式的主要问题是
    • 多个js文件中的同名变量会冲突
    • js文件之间无法相互引用
  • 通过模块化解决上述问题
    • 模块化就是把单独的一个功能独立封装成一个模块(文件),模块相互隔离,但是可以通过特定的接口,暴露成员,或者依赖别的模块
    • 模块化的好处:后期易维护,提高了开发效率,方便代码的重用

(浏览器,服务器,ES6)模块化

  1. 浏览器模块化规范

    浏览器模块化

    • 这两个模块化规范,已经落伍了,知道就好

2 . 服务器端模块化规范

commonjs

​ 浏览器和服务器都有各自的模块化规范, 但是还不统一,重点看ES6统一规范

​ 每一个模块都一个文件,都有自己的作用域

  1. ES6模块化规范

    • 上述的模块化标准存在一定的差异性与局部性,并不是通用的模块化标准,因此在ES6的语法上,定义了通用性的ES6模块化规范。

          ES6模块化规范中定义:
              1).每一个js文件都是独立的模块
              2).导入模块成员使用import关键字
              3).暴露模块成员使用export关键字
      

    小结:推荐使用ES6模块规范, ES6模块化是浏览器端和服务器端通用的规范.

在NodeJs中安装babel体验ES6模块化

  • node默认支持commonjs这种服务器端的模块化
  • 但是对于ES6模块化支持的不是太好,所以使用第三方工具babel
  • babel是一个语法转换工具,可以将高级的有兼容问题的代码,转换为低级的无兼容问题的代码
  1. 安装babel

    打开终端,输入命令:npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
    安装完毕之后,再次输入命令安装:npm install --save @babel/polyfill
    
    
    注意:如果npm安装上诉包不成功,就使用cnpm
    但是需要安装cnpm:
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    
  2. 创建babel.config.js文件

    下述是配置babdl
    编辑js文件中的代码如下:
    const presets = [
        ["@babel/env",{
            targets:{
                edge:"17",
                firefox:"60",
                chrome:"67",
                safari:"11.1"
            }
        }]
    ]
    //暴露
    module.exports = { presets }
    
  3. 创建index.js文件

    在项目目录中创建index.js文件作为入口文件
    在index.js中输入需要执行的js代码,例如:
        console.log("ok");
    
  4. 使用npx执行文件

    打开终端,输入命令:npx babel-node ./index.js
    
  5. 效果

    babel效果

ES6模块化语法

  • 默认导出与默认导入

  1. 默认导出

    //导出语法:expotr default{ }
    
    export default {
        成员A,
        成员B,
        .......
    }
    
    例子
    let num = 100;
    export default{
        num
    }
    
  2. 默认导入

    //导入语法 impotr 接收名称 from '模块标识符'
    
    import 接收名称 from "模块标识符",
    例子:
    import test from "./test.js"
    

    注意:一个模块中只允许一次导出,只能使用一个export default ,否则会报错

    如果一个模块中没有向外暴露成员,其他模块导入该模块得到的只是一个空对象

  • 按需导出与按需导入

    • 介绍

    按需导出

    • s2 as ss2 中 as 是用来起别名,起过别名,使用的时候只能使用ss2
    • 按需导入,需要添加{}
    • 在一个模块中按需导出可以使用多次,(一个模块中默认导出只能使用一次)
    • 一个模块中既可以按需导入也可以默认导入,导出同理
  • 直接导入并执行代码

    • 绍介

      直接导入

    • m2并没有导出任何内容,只是定义了一段代码

    • index直接导入了m2整个文件代码,并没有导入某个,某些数据

webpack

  • 在前端开发中 vue, react, angular三大前端框架都依赖于webpack来做打包的。(用这个三个框架来开发项目,都离不开webpack)
  • webpack现状

介绍webpack的作用

  • 当前的web开发面临的困境

    • 文件依赖关系错综复杂
    • 静态资源请求效率低
    • 模块化支持不太友好
    • 浏览器对高级的javascriptr ( ES6模块化语法) 特性兼容程度较低
  • 解决

    • webpcak是一个流行的前端项目构建工具(打包工具),可以解决目前web开发面临的困境
    • webpcak提供了友好的模块化支持,解决了js的兼容性,性能优化等特性,提高开发效率,提高项目后期的可维护性
    • webpack,(pack:包裹,包装。) 理解为web打包工具

创建项目(安装和配置webpack)

  • 创建项目

    • 1. 新建项目空白目录,并运行 npm init -y 命令 ,初始化包管理配置文件 package.json
      2. 新建 src 源代码目录
      3. 新建 src -> index.html 首页
      4. 打开项目目录终端运行 npm install jquery -s 命令,安装 jQuery
      5. 通过 ES6模块化语法 import $ from "jquery",默认导入jQuery实现功能
      
      • 第一步 初始化包管理文件
        • -y 的含义:yes的意思,在init的时候省去了敲回车的步骤(前提是项目目录不含中文)
      • 第五步:src 文件
        • 默认打包 src 路径下的 js文件
      • 第四步 -s 的含义
        • -S:--save,缩写为-S,表示安装的包将写入package.json里面的dependencies
        • -D:--save-dev,缩写为-D,表示将安装的包将写入packege.json里面的devDependencies
        • -g :--global,缩写为-g,表示安装包时,视作全局的包。安装之后的包将位于系统预设的目录之下,一般来说 。
      • 第五步 浏览器对ES6模块化语法 存在兼容性问题,需要webpack解决这个问题
  • 安装webpack

    • webpack可以支持部分的ES6模块化语法的转换,如果想支持所有的还需要babel的支持

    • babel会处理webpack处理不了的语法

    • 1. 打开项目目录终端。运行 npm install webpack webpack-cli -D
      2. 在项目目录文件中创建名为 webpack.config.js 的 webpack配置文件
      3. 在 webpack配置文件中初始化如下基本配置: 
         module.exports = {
          mode:"development"//可以设置为development(开发模式),production(发布模式)
          }
      4. 在 package.json 配置文件中的scripts 节点下,新增 dev 脚本如下
          scripts":{
          "dev":"webpack"
          }
      5. 在项目目录终端。运行 npm run dev 命令,启动webpack进行项目打包
      6. 打包完毕之后,找到默认的dist路径中生成的main.js文件,将其引入到html文件中
      
      • 第三步: mode有两种
        • development:开发模式,打包的代码不会压缩和混淆
        • production:生产模式(正式上线模式),打包的代码会压缩和混淆
      • 第五步:scripts节点下的脚本,可以通过 npm run 运行
        • npm run dev (webpack 打包)
        • npm run lint ( vuecli提供的自动修复功能 )
        • npm run serve (启动开发服务)
  • 配置打包的入口与出口

    • 在webpack 4.x中 ,默认的打包入口和出口

    • 修改默认打包入口和出口:

      • 如果不想使用默认的入口/出口js文件,我们可以通过改变 webpack.config.js 来设置入口/出口的js文件

        • const path = require("path");
          module.exports = {
              mode:"development",
              //设置入口文件路径
              entry: path.join(__dirname,"./src/xx.js"),
              //设置出口文件
              output:{
                  //设置输出文件的存放路径
                  path:path.join(__dirname,"./dist"),
                  //设置输出文件名
                  filename:"res.js"
              }
          }
          
          • path.join用来拼接路径
          • __dirname表示为当前文件的根目录
  • 配置webpack的自动打包功能

    • 为什么需要自动打包

      • 因为修改代码之后 ,需要重新打包才能看到效果
      • 但是每次 修改 代码, 都要手动 执行: npm run dev 太麻烦
    • 自动打包步骤

      • 1.  运行 npm install webpack-dev-server -D 命令, 安装自动打包工具 webpack-dev-server
        2.  修改 packege.json -> scripts 中的dev 命令
              "scripts":{
                    "dev":"webpack-dev-server"
                }
        3.  将引入到html的js文件路径更改为:比如<script src="/main.js"></script> 根路径
        4.  运行 npm run dev 命令,重新进行打包
        5.  在浏览器中访问 http://localhost:8080
        
      • 第三步 在html中将引入 的js文件路径更改为根路径

    • 注意,打包之后,输出文件main.js默认被放到了根路径下

      • 第五步 为什么使用 http://localhost:8080 + /src 访问

        • 注意: 使用了webpack-dev-server命令打包之后,只能通过localhost:8080这样的地址访问,直 接访问index.html是不行的
  • 配置html-webpack-plugin生成预览页面

    • 想访问localhost:8080之后直接看到index.html,怎么办?

      • 预览界面设置:html-webpack-plugin就是生成预览界面的插件

      • 预览页面步骤

      • 具体配置代码(可以复制)

        //A.安装默认预览功能的包:html-webpack-plugin
        	npm install html-webpack-plugin -D
        //B.修改webpack.config.js文件,如下:
            //导入包
            const HtmlWebpackPlugin = require("html-webpack-plugin");
            //创建对象
            const htmlPlugin = new HtmlWebpackPlugin({
                //设置生成预览页面的模板文件
                template:"./src/index.html",
                //设置生成的预览页面名称
                filename:"index.html"
            })
        //C.继续修改webpack.config.js文件,添加plugins信息:
            module.exports = {
                ......
                plugins:[ htmlPlugin ]
            }
        
      • 补充:在自动打包完毕之后,默认打开服务器网页,实现方式就是打开package.json文件,修改dev命令:"dev": "webpack-dev-server --open --host 127.0.0.1 --port 9999"

  • 配置自动打包相关的参数

    • 问题:当我们执行完打包命令,需要手动访问localhost:8080才能看到首页,太麻烦

    • 配置参数:以下配置为自动打开浏览器访问首页

      自动打开首页

      • ip一般是127.0.0.1,localhost
      • port默认是8080,可以修改为8888

webpack中的loader加载器(loader官网)

  • 通过loader打包非js文件

    • 在实际开发过程中,webpack 默认只能打包处理 .js后缀结尾的文件(模块),其他非 .js 文件。webpack是处理不了,需要调用 loader 加载器才可以正常打包, 否则报错

    • loader加载器包含:
             1).less-loader   //打包less文件
             2).sass-loader   //打包sass文件
             3).url-loader    //打包处理css中与url路径有关的文件
             4).babel-loader   //处理高级js语法的加载器
             5).postcss-loader  //自动给css添加兼容前缀
             6).css-loader,style-loader // 打包 scc文件
             
      // 注意:指定多个loader时的顺序是固定的,而调用loader的顺序是从后向前进行调用
       
      
  • loader调用过程

    loader调用过程

  • 打包处理css文件

    • 演示在没使用loader加载器的情况下

      打包css报错

      • index.js为啥要引入 1.css ?因为默认打包的是index.js,所以需要把1.css引入
      • 为啥会报错,因为webpack默认只能打包后缀为.js的文件,要想打包其他文件需要loader加载器
    • 步骤

      • 1. 运行 npm i style-loader css-loader -D 命令,安装处理 css文件的 loader
        2.  在 webpack.config.js配置文件中新增一个节点module->rules 数组中,添加loader规则如下:
                module.exports = {
                 //所有的第三方文件模块的匹配规则 
                  module : {
                     rules:[
                        {
                            //test设置需要匹配的文件类型,支持正则
                            test:/\.css$/,
                            //use表示该文件类型需要调用的loader
                            use:['style-loader','css-loader']
                        }
                     ]
                   }
                }
            
         //  text表示匹配的文件类型,use表示对应要调用的loader
         //use:['style-loader','css-loader'] 的匹配文件顺序是固定的, 执行文件的顺序是从后向前执行
        
        • rules:存放所有的loader规则
        • test接收一个正则表达式//,这个正则表达式只需要匹配文件的后缀即可
        • \.代表点,css$表示以css结尾,其实就是以.css结尾
        • use接收一个数组,打包css文件,需要style-loader,和css-loader
    • 配置之后,重新打包,最后访问

  • 打包处理less文件

    • 步骤

      1. 运行 npm i style-loader css-loader -D 命令,安装处理 css文件的 loader
      2. 运行 npm install less-loader less -D 命令,安装处理 less文件的loader
      3.  在 webpack.config.js配置文件中新增一个节点module->rules 数组中,添加loader规则如下:
              module.exports = {
               //所有的第三方文件模块的匹配规则
                module : {
                   rules:[
                      {  //test设置需要匹配的文件类型,支持正则
                          test:/\.less$/,
                          //use表示该文件类型需要调用的loader
                          use:['style-loader','css-loader','less-loader']
                      }
                   ]
                 }
              }
          
       //  text表示匹配的文件类型,use表示对应要调用的loader
       //use:数组中的loader文件顺序是固定的, 执行文件的顺序是从后向前执行
      
      • less文件打包队了需要less-loader,也需要依赖 style-loader,css-loader
      • 也需要 import 将less文件引入到 index.js中
  • 打包处理 scss文件

    • 步骤

      1. 运行 npm i style-loader css-loader -D 命令,安装处理 css文件的 loader
      2. 运行 npm install less-loader scss -D 命令,安装处理 css文件的loader
      3.  在 webpack.config.js配置文件中新增一个节点module->rules 数组中,添加loader规则如下:
              module.exports = {
               //所有的第三方文件模块的匹配规则
                module : {
                   rules:[
                      {
                          //test设置需要匹配的文件类型,支持正则
                          test:/\.less$/,
                          //use表示该文件类型需要调用的loader
                          use:['style-loader','css-loader','scss-loader']
                      }
                   ]
                 }
              }
          
       //  text表示匹配的文件类型,use表示对应要调用的loader
       //use:数组中的loader文件顺序是固定的, 执行文件的顺序是从后向前执行
      
    • 也需要 import 将scss文件引入到 index.js中

  • 配置postCSS(自动添加css的兼容前缀)

    • 配置postCSS自动添加css的兼容前缀(-ie-,-webkit-)

      1. 运行 npm i style-loader css-loader -D 命令,安装处理 css文件的 loader
      2.  运行 npm install postcss-loader autoprefixer -D 命令
      3.  在项目根目录中创建 postcss的配置文件postcss.config.js,并初始化如下配置
              const autoprefixer = require("autoprefixer"); //导入自动添加前缀的插件包
               module.exports = {
                  plugins:[ autoprefixer ] //挂载插件
               }
      4. 在 webpack.config.js配置文件中新增一个节点module->rules 数组中,添加loader规则如下:
            module.exports = {
                   //所有的第三方文件模块的匹配规则
                    module : {
                       rules:[
                          {
                              //test设置需要匹配的文件类型,支持正则
                              test:/\.less$/,
                              //use表示该文件类型需要调用的loader
                              use:['style-loader','css-loader','postcss-loader']
                          }
                       ]
                     }
                  }
              //  text表示匹配的文件类型,use表示对应要调用的loader
               //use:数组中的loader文件顺序是固定的, 执行文件的顺序是从后向前执行
      
  • 打包样式表中的图片和字体文件

    • 在样式表css中有时候会设置背景图片和设置字体文件,一样需要loader进行处理

      1. 运行 npm install url-loader file-loader -D
      2. 在 webpack.config.js配置文件中新增一个节点module->rules 数组中,添加loader规则如下:
           module.exports = {
                       //所有的第三方文件模块的匹配规则
                        module : {
                           rules:[
                             {
                              test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
                              use:"url-loader?limit=16940"
                               //limit用来设置字节数,只有小于limit值的图片,才会转换为base64图片
                               }
                           ]
                         }
                      }
                      //  text表示匹配的文件类型,use表示对应要调用的loader
                      //use:数组中的loader文件顺序是固定的, 执行文件的顺序是从后向前执行
      
      • use:可以接收loader数组,也可以接收一个loader名称(字符串)
    • limit 用来指定图片的大小,单位是字节(byte)只有小于limit大小的图片,才能会被转为base64图片,如果大于或等于就不会将图片的路径转换成base64编码。

  • 打包处理js文件中的高级语法

    • webpack只执行一部分的ES6新语法,他需要配合babel才可以完全支持ES6新语法

    • webpack不能处理es6的新特性

    • 所以需要用babel将不被兼容的js语法打包为兼容的js代码

      1. 安装babel转换器相关的包  npm install babel-loader @babel/core @babel/runtime -D
      2. 安装babel语法插件包  npm install @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
      3. 在项目根目录中,创建babel配置文件,并配置babel.config.js文件 如下 
          module.exports = {
             presets:["@babel/preset-env"],
             plugins:[ "@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties" ]
          }
      4. 在 webpack.config.js配置文件中新增一个节点module->rules 数组中,添加loader规则如下:
        module.exports = {
                       //所有的第三方文件模块的匹配规则
                        module : {
                           rules:[
                               {
                              test:/\.js$/,
                              use:"babel-loader",
                              exclude:/node_modules/
                               //exclude为排除项,意思是不要处理node_modules中的js文件
                             }
                           ]
                         }
                      }
      
      • node_modules是第三方提供的js代码,这些代码不需要webpack打包
      • webpack只打包程序员自己的代码
  • 配置.vue文件的loader加载器

    • 配置vue组件的加载器

      1. 安装vue组件的加载器 npm install vue-loader vue-template-compiler -D
      2. 在webpack.config.js配置文件中,添加vue-loader的配置项如下 
          const VueLoaderPlugin = require("vue-loader/lib/plugin");
           module.exports = {
                   // 引入这个vue的加载器插件
                  plugins:[ new VueLoaderPlugin()],
                     
                       //所有的第三方文件模块的匹配规则
                        module : {
                           rules:[
                             {  test:/\.vue$/, loader:"vue-loader"}
                           ]
                         }
                      }
      
  • 其他loader加载器

vue的单文件组件介绍