浅谈webpack构建项目

webpack

webpack的前因

在网页之中引入那些静态资源

  • 1:样式表
    • .css .less .sass .scss
  • 2:javascript脚本
    • .js .ts .coffee
  • 3:img
    • .png .jpg .webp .gif
  • 4:模板文件
    • .vue .ejs
  • 5:字体文件(Fonts)
    • .eot .svg .ttf .woff

上述的静态资源过多后,会造成一定的影响!

  • 1:加载慢
    因为静态资源多,需要发起多次二次请求,使得网页的加载速度变得慢了!

  • 2:会存在静态资源的互相依赖问题!

  • 解决方案:
    1:把img图标等合并为精灵图,把图片或js合并,并且压缩一下
    2:把图片转化为base64的编码格式(以字符串的形式存在!)
    <img src="./1.png /> 转化为base64的方式 <img src="base64:image....
    浏览器解析的时候,识别这些base64编码,转化为一个img渲染到页面(不用像 ./1.png方式,需要再发起一次请求! )
    3:使用webpack来解决静态资源的依赖性问题!(因为这是使用了CommonJS的导包原理,一并把所依赖的包一起打包起来!)

webpack的介绍之 开发篇

  • 概念:webpack是前端构建项目的一个工具,这个工具可以使用项目更好维护,更好把控!

  • 应用场景:webpack构建项目非常适合结合单页面应用程序;不适合多页面应用程序!

  • 作用:

    • 1:能够处理静态资源的依赖关系
    • 2:能够对静态资源的合并或压缩,减少文件的大小!
    • 3:能把高级语法转化为低级语法
    • 4:webpack可以转化一些模板文件 .vue(就是一个组件)等!
  • 安装:

    • 1:全局安装webpack
      npm || cnpm i webpack -g 可以选择npm或者cnpm
      webpack -v => 查看安装的版本!
      会提示你安装 webpack cli 安装即可!
    • 2:项目之中安装webpack => 使用的最多的方式
      npm i webpack -D => 安装到开发项目依赖!
  • 最原始的打包方式(构建项目方式)

    • 1:webpack ./src/main.js ./dist/bundle.js //=> webpack 将指定的文件(处理的文件) 打包到 指定的文件夹之中(输出路径)
    • 2:webpack ./src/main.js -o ./dist/bundle.js //上面的指令保错的话就执行这一行指令!
  • 想要使用webpack脚本命令直接构建项目的话,则需要配置文件

    • 注意点:就是webpack默认情况下,只能打包 .js文件,需要打包 其他后缀名的文件 那么需要相对应的loader加载器!
    • 在项目目录下,创建一个webpack.config.js文件!
      • 在这个配置文件之中,需要明确的声明, 要处理的文件路径 还有要输出的文件路径
        注意点:就是webpack这个项目构建工具的底层就是使用node.js开发的,因此需要使用
        导出: module.exports = {}
        导入: const ? = require('需要导入的模块')
      const path = require("path");
      module.exports = {
        //指定要处理的文件路径
        entry: path.join(__dirname, "./src/main.js"),
        //指定要输入文件路径 和 文件名
        output: {
          path: path.join(__dirname, "./dist"), //路径
          filename: "bundle.js" //文件名
        }
      }
      
      • 配置完毕后,在终端之中,输入webpack命令即可! 但是每一次修改后,还需要输入命令,还是很繁琐,因此需要一个自动监听的服务器来实现自动监听代码更新效果。显示最新的效果!

配置webpack-dev-server方式1

  • 注意点:配置webpack-dev-server需要在上述的基本配置上添加以下的需求:

  • 目的:实现实时的代码编译和刷新浏览器!

  • 使用webpack-dev-server 第一种方式 => 实现文件的更新,自动刷新代码实现的效果!推荐使用的方式!

    • 安装:npm i webpack-dev-server -D
    • 这个包还依赖于与webpack包(项目本地),因此还需要下载webpack包
      npm i webpack -D
      由于webpack-dev-server是安装在项目之中的,无法直接输入指令开启,因此还需要在package.json文件中自定义脚本命令
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "dev": "webpack-dev-server" //执行 npm run dev 后 会根据这个脚本指令,去配置项寻找暴露的配置文件执行!
    }
    

    由于webpack-dev-server还依赖于脚手架,需要下载才能使用
    npm i webpack-cli -D
    运行的时候npm run dev 结果会开启一个服务器**http://localhost:8080/**通过这个url路径访问(浏览器)

    i 「wds」: Project is running at http://localhost:8080/  => 项目运行这个服务之中 (可以在浏览器中访问)
    i 「wds」: webpack output is served from /  => 这个服务的输出文件被托管于当前文件目录 / 也就是说 (http://localhost:8080/bundle.js 可以访问!,那么就是可以在html之中,利用这个路径来导入!) 
    // `<script src="/bundle.js"></script> html中引入! 但是大部分都是使用html-webpack-plugin 插件来自动引入的`
    i 「wds」: Content not from webpack is served from D:\xzl_HTML5\010vue\VueBase\day04webpack\01webpack-table
    既然如此的话,
    
    • 注意点:使用webpack-dev-server这个工具,自动打包的bundle.js文件没有打包到实际的磁盘之中,而是隐秘地托管在内存之中(其实也可以认为托管在根目录之中!但是看不着,却实际存在)
      • 保存在内存之中,有着更快的写入,提高保存速度运行速度,还有与磁盘一比,写入更快!
  • 想要编译完成后,自动打开浏览器,那么需要在package.json文件配置参数 也就是对脚本命令(dev) 在添加 --open

    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "dev": "webpack-dev-server --open" //注意点:这边还可以指定端口号 还有ip地址 --port 3000 --host 127.0.0.1 
      // --hot(热跟新,就是不再重新生成bundle.js,index.html而是以补丁的方式,往旧的文件打入新的更改,效率更高一些!)
    }
    

配置webpack-dev-server方式2 不推荐

  • 使用webpack-dev-server 第二种方式 => 实现文件的更新,自动刷新代码实现的效果!
    • 1:下载插件和引入插件
      npm i webpack open-browser-webpack-plugin -D
    • 2:在package.json文件中配置这个脚本指令
      "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1",
       "dev2": "webpack-dev-server"
      }
      
    • 3:在webpack.config.js文件中创建一个服务,为了自动打开浏览器和热更新等!
    module.exports = {
      //指定要处理的文件路径
      entry: path.join(__dirname, "./src/main.js"),
      //指定要输入文件路径 和 文件名
      output: {
        path: path.join(__dirname, "./dist"), //路径
        filename: "bundle.js" //文件名
      },
      //关于插件相关的数组
      plugins: [
        new htmlWebpackPlugin({ //这是把html页面保存在内存之中
          template: path.join(__dirname, "./src/index.html"), //就是所要复制模板,保存在内存之中
          filename: "index.html" //将来在内存之中复制出来的模板,名称为index.html
        }),
        new webpack.HotModuleReplacementPlugin()
      ],
      // 关于自动打开浏览器的脚本指令
      devServer: {
        open: true, //自动打开浏览器
        port: 3000, //端口号
        host: "127.0.0.1", //ip地址
        hot: true, //启动热跟新,在这边的haul,需要配合插件的使用
      }
    }
    

初步使用webpack打包构建列表隔行变色案例

执行打包 (最原始的打包方式) => 后面有着更为方便的方式

  <ul>
    <li>我是1个小li</li>
    <li>我是2个小li</li>
    <li>我是3个小li</li>
    <li>我是4个小li</li>
    <li>我是5个小li</li>
    <li>我是6个小li</li>
    <li>我是7个小li</li>
    <li>我是8个小li</li>
    <li>我是9个小li</li>
    <li>我是10个小li</li>
  </ul>
  <script src="../dist/bundle.js"></script>
import $ from "jquery";
$(function () {

  $("ul li:odd").css({
    "background": "red"
  })
  $("ul li:even").css({
    "background": "yellow"
  })
})

webpack之plugin(插件)

html-webpack-plugin插件

  • 目的:操作html的插件,可简化HTML文件的创建以服务你的webpack捆绑软件
    • 把html文件生成到内存中的插件!
    • 于是在内存之中保存了一份index.html文件,使用http://localhost:8080/index.html可以访问到
    • 注意点:这个插件还有一个功能,就是会把那个bundle.js自动注入到index.html文件之中,因此不需要在手动导入!
  • 安装:
    npm install html-webpack-plugin -D
  • 使用:
    • 在webpack.config.js文件之中,引入这个插件,并且使用
      const path = require("path");
      //引入一个使得html页面生成,保存在内存之中
      const htmlWebpackPlugin = require("html-webpack-plugin"); //导入的是一个构造函数
      
      module.exports = {
        //指定要处理的文件路径
        entry: path.join(__dirname, "./src/main.js"),
        //指定要输入文件路径 和 文件名
        output: {
          path: path.join(__dirname, "./dist"), //路径
          filename: "bundle.js" //文件名
        },
        //关于插件相关的数组
        plugins: [
          new htmlWebpackPlugin({ //这是把html页面保存在内存之中
            template: path.join(__dirname, "./src/index.html"), //就是所要复制模板,保存在内存之中
            filename: "index.html" //将来在内存之中复制出来的模板,名称为index.html
          })
        ]
      }
      
      • 最后执行 npm run dev

webpack之loader(加载器)

  • 注意点1:main.js是打包的入口文件,那么所有的第三方文件 .css .less .js 什么的都应该导入这个这个文件,然后一并打包到bundle.js文件之中!
  • 注意点2:
    • 1:webpack默认只是处理 .js文件
    • 2:非js文件,先去webpack.config.js文件中导出的的module模块中的rules规则中查找,若是存在,那么就执行,
      若是不存在,那么就报错 You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders appropriate loader 合适的加载器
    • 3:loader调用顺序,是从后面到前面的,后面处理后,把结果返回给前面的loader,loader处理完毕后,最后一个loader会返回给webpack,让webpack拿着最终的结果,打包到bundle.js文件之中!
    • 4:webpack 只关心非js文件的处理结束的结果,直接打包到bundle.js文件,不会关心第三方loader的处理过程!

处理 .css后缀名文件,需要的加载器(style-loader 和 css-loader)

  • 安装:
    npm i style-loader css-loader -D
  • 使用:
    • 在main.js文件之中引入 .css文件
      import mystyle from "./css/XX.css"
    • 或者这种写法 import "./css/XX.css 只是导入了样式表! 使用这种方式更好
      在webpack.config.js文件中配置 .css文件 和 加载器的规则! 就是module这部分的匹配规则!
      const path = require("path");
      
      //引入操作html文件 实现
      const htmlWebpackPlugin = require("html-webpack-plugin")
      
      module.exports = {
        entry: path.join(__dirname, "./src/main.js"),
        output: {
          path: path.join(__dirname, "./dist"),
          filename: "bundle.js"
        },
        //插件相关的
        plugins: [
          new htmlWebpackPlugin({
            template: path.join(__dirname, "./src/index.html"),
            filename: "index.html"
          })
        ],
        //配置非js文件的模块加载 loader
        module: {
          rules: [ //配置 非js文件 和 loader的对应关系!
            {
              test: /\.css$/, //匹配以.css文件结尾的文件 
              use: ['style-loader', 'css-loader'] //然后使用这个两个加载器去处理!
            }
          ]
        }
      }
      

处理 .less后缀名文件,需要的加载器(less-loader less)

  • 注意点:就是less是 less-loader的内置依赖项,不需要配置loader规则里面!
  • 安装:
    npm i less-loader -D
  • 引入: 在main.js文件中引入
    import "./css/index.less"
  • 配置: 在webpack.config.js文件中配置 => module => rules
      //这边省略了 module.export = {} 和 .css配置项一样! 
      //配置非js文件的模块加载 loader
      module: {
        rules: [ //配置 非js文件 和 loader的对应关系!
          {
            test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader'] //匹配less,处理好后,返回给css处理,最后返回给webpack打包到 bundle.js
          }
        ]
      }
    

处理 .scss后缀名文件,需要的加载器(sass-loader node-sass)

  • 安装:
    cnpm i sass-loader -D
    cnpm i node-sass -D
  • 引入:在main.js文件中引入
    import "./css/XXX.scss

处理 img文件,需要的加载器(url-loader file-loader)

  • 注意点:就是file-loader是url-loader的内置项,只需要安装即可,不需要配置!
  • 安装:
    npm i url-loader -D
    npm i file-loader -D
  • 引用:
    .box {
      width: 200px;
      height: 200px;
      background: #000 url("../images/vue之命名视图,实现同一个路径显示多个组件.png");
    }
    
  • 配置:在webpack.config.js文件中 module => rules
    {
      test:/\.jpn|png|gif|.webp$/,//等img的后缀名
      use: ["url-loader?limit=1190&name=[name].[ext]"] //匹配 img的各种后缀 处理后打包!
      //limit这是给url-loader传递参数,其中有这样一个参数为limit,表示图片的大小,给定一个数值即可!(字节的单位)
      //如果指定了limit参数,则只有图片的大小,小于给定的值的时候,才会转为base64编码,否则就不会转换!
      //name=[name].[ext] => img文件打包前是什么名字还有什么后缀就是原始打包上去
      //name=[hash:6][name].[ext] => 为了实现两种img不重名,出现覆盖,可以这样设置!
    }
    

处理 es6高级语法转化为es5语法,需要两套包的搭配使用

  • 01:
    npm i babel-core babel-loader@7 babel-plugin-transform-runtime -D
    webpack.config.js配置babel-loader,其他两个是他的内置依赖包 注意点:babel-loader@7 版本为7.X
  • 02:
    npm i babel-preset-env babel-preset-stage-0 -D
    注意点:就是以babel-preset开头的包是Babel语法 就是以babel-plugin开头的包是Babel插件
  • 03:在webpack.config.js文件配置
        {
          test: /\.js$/,
          use: "babel-loader",
          exclude: /node_modules/ //添加转化js文件的loader,必须把node_modules目录下的js排除掉!这样才会忽略掉node_modules
          //就是匹配到这个.js文件,使用babel-loader进行转换,但是babel-loader不识别语法,因此还需要一个配置文件(识别高级语法和低级语法的字典库! => .babelrc)
        }
    
  • 04:在项目根目录下,创建一个babel的配置文件 .babelrc 在里面写配置!
    {
      "plugins": ["transform-runtime"],
      "presets": ["env", "stage-0"] //语法
    }
    
  • 05:关于babel的吧ES6转化为ES5的过程
    • 1:把es6拉取到babel之中,进行加工
    • 2:babel-loader:只是负责进行转换,但是不知道高级语法还是低级语法
    • 3:babel-preset-env 和 babel-preset-stage-0 高级语法转化为低级语法的字典库

webpack的介绍之 发布篇

1:其实在实际开发之中,webpack有着两套方案,一套关于开发时方案,一套关于发布时的方案

  • 开发时的方案:这里面包含着测试文件,开发工具,测试数据等配置,有利于开发和测试,但是这些文件只是用于开发而言,发布时会剔除掉!
  • 发布时的方案:剔除了那些用户用不到的测试工具和文件后,使得项目变得干净清晰,减少项目体积,有利于项目的安装和部署!

发布时的配置文件

  • 1:在项目的根目录下,创建一个webpack.publish.config.js => 这是关于项目发布的配置文件!
  • 2:在package.json文件配置发布时的脚本命令 => npm run pub =>执行的指令!
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "dev": "webpack-dev-server --open --hot",
      // "pub":"webpack" //只是配置这个的话,会加载默认的配置文件 **webpack.config.js** 但是发布时,需要加载的是**webpack.publish.config.js文件**,因此需要在后面指定,需要加载的配置文件!
      "pub": "webpack --config webpack.publish.config.js"
    }
    
  • 3:输入的时候
    output: {
      path: path.join(__dirname, "./dist"),
      filename: "index.js" //修改为index.js文件! 以作区分
    },
    
对images路径的添加前缀,存放在统一的文件夹上
  • webpack.publish.config.js文件中的module=> rules => 的匹配img中添加
{
  test: /\.jpg|png|gif|webp$/,
  use: ["url-loader?limit=1190&name=images/[name].[ext]"] //匹配 img的各种后缀 处理后打包!
  //limit这是给url-loader传递参数,其中有这样一个参数为limit,表示图片的大小,给定一个数值即可!(字节的单位)
  //如果指定了limit参数,则只有图片的大小,小于给定的值的时候,才会转为base64编码,否则就不会转换!
},
每一次发布的时候,都把dist文件夹中的老文件清空,只打包显示最新的文件!
  • 安装:
    npm i clean-webpack-plugin@2 -D
  • 引入后配置 在webpack.publish.config.js=> 引入和配置
    const clearPlugin = require("clear-webpack-plugin)
  • 配置:
    plugins: [
      new htmlWebpackPlugin({
        template: path.join(__dirname, "./src/index.html"),
        filename: "index.html"
      }),
      new clearPlugin() //在这边写入每一次开发版本更新的时候,需要清除的文件,
    ],
    

对目录的分离 之webpack4.X版本的!

  • 0:官网:https://www.webpackjs.com/plugins/split-chunks-plugin/
    在使用splitChunksPlugins之前,首先要知道splitChunksPlugins是webpack主模块中的一个细分模块,无需npm引入。
    功能上:splitChunksPlugins只能用于如何抽离公用的代码,也就是抽离公用代码的规则,要记住,除了这个功能之外,splitChunksPlugins再无其他功能 参考:https://www.cnblogs.com/cangqinglang/p/10796534.html

    0: optimization => 优化 
    1:splitChunks => 拆分块!
    2:cacheGroups
      名字叫做缓存组,其实就是存放分离代码块的规则的对象,叫做cacheGroup的原因是webpack会将规则放置在cache流中,为对应的块文件匹配对应的流,从而生成分离后的块。
      cacheGroup中priority 为分离规则的优先级,优先级越高,则优先匹配。
    3:vendor => 第三方目录
    4.test
      用于规定缓存组匹配的文件位置,test: /node_modules/  即为匹配相应文件夹下的模块
    5.name
      用以控制分离后代码块的命名,当存在匹配的缓存组(后面会说到)时,命名使用缓存组中的name值,若不存在则为  [来源]~[入口的key值].js  的 格式
    6.chunks
      匹配的块的类型:initial(初始块),async(按需加载的异步块),all(所有块)
    7. minSize 
      分离后的最小块文件大小,单位为字节
    8. minChunks
      分离前,该块被引入的次数(也就是某个js文件通过import或require引入的次数)
    
  • 1:开发的代码:打包保存在dist目录

  • 2:第三方插件:打包到vendors目录(也就是第三方包的名称)

    • 因此需要对webpack.publish.config.js文件修改入口文件和输出文件
      • 导入webpack包
        const webpack = require("webpack");
      • 引入清除每一次发布前的dist目录
        const clearPlugin = require("clean-webpack-plugin")
      • 把模块的入口文件修改为app和vendors,就是项目主文件和下面第三方包
          entry: {
            app: path.join(__dirname, "./src/main.js"), //这是项目的主文件
          }
        
      • 把公共的部分抽离出来(比如jq啊) => 使用optimization的配置项来配置(注意点:这个配置项和entry,output同级别!)
          optimization: {//优化
            splitChunks: {//分割快
              cacheGroups: {//缓冲组
                commons: {
                  name: "vendors",//打包后的名称
                  chunks: "initial",
                  minChunks: 1,
                }
              }
            }
          }
        

最终相关代码

//导入webpack包
const webpack = require("webpack");
//引入,清除发布时的文件
const clearPlugin = require("clean-webpack-plugin")

module.exports = {
  entry: {
    app: path.join(__dirname, "./src/main.js"), //这是项目的主文件
  },
  output: {
    path: path.join(__dirname, "./dist"),
    filename: '[name].js' //也可以在这边设置目录 'js/[name].js' => 这个name拿到之前的name,不修改名!
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          name: "vendors",
          chunks: "initial",
          minChunks: 1,
        }
      }
    }
  },
  ..... 中间 ...
}

webpack之压缩 和 转化

webpack之压缩js

  • 官网:https://webpack.docschina.org/plugins/uglifyjs-webpack-plugin/#root
    选择uglifyOptions => 移除警告灯信息
    选择Options => 进行相关的配置!

  • 安装:
    npm install uglifyjs-webpack-plugin --save-dev

  • 引入: 在webpack.publish.config.js
    const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

  • 配置项的解析:

      1:optimization => 优化
      2:minimizer => 最小值 (也就是压缩)
    
  • 使用:optimization=>minimizer最小值!

    
    
  • 使用DefinePlugin插件,实现对第三方包的优化

  • 官网:https://webpack.docschina.org/plugins/define-plugin/

        new webpack.DefinePlugin({ //本插件的作用:就是在全局作用域下配置的全局变量,为了给第三方插件使用的,
        // 比如vue,还会检查webpack检查这个字段PRODUCTION,为发布环境阶段,那么会移除掉警告,并且做优化!
        PRODUCTION: JSON.stringify(true),
        "myVar": "'123'"
      }),
    

webpack4之css,less,scss抽离与压缩

抽离 mini-css-extract-plugin
  • 官网:https://webpack.docschina.org/plugins/mini-css-extract-plugin/#root
  • 安装:
    npm install --save-dev mini-css-extract-plugin
  • 引入:
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  • 使用:使得css不会被压在到index.js,抽离到一个样式表之中!
    module.exports = {
      new MiniCssExtractPlugin({
        filename: 'css/[name].css',
      }),
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: [{
              loader: MiniCssExtractPlugin.loader,
              options: {
                publicPath: '../', //公共的路径,为了在dist中的index.html能使用到这些css等!
                },
              },
              'css-loader',
            ],
          },
                  {
            test: /\.less$/i,
            // 这是对于less和scss的提取  还是需要定义在一个匹配对象上的,为了方便就跳过了!
            use: [ .... 类似上面的css,  'css-loader', 'less-loader'],
            use: [ .... 类似上面的css, 'css-loader', 'sass-loader'],
          },
        ],
      },
    };
    
压缩 optimize-css-assets-webpack-plugin
  • 安装:
    npm i optimize-css-assets-webpack-plugin -D
  • 引入:
    //普通压缩
    plugins: [ 
     new OptimizeCSSAssetsPlugin ()
    ]
    
    // 使用cssnano配置规则
    // 先 npm i cssnano -D
    plugins: [ 
      new OptimizeCSSAssetsPlugin ({
        // 默认是全部的CSS都压缩,该字段可以指定某些要处理的文件
        assetNameRegExp: /\.(sa|sc|c)ss$/g, 
        // 指定一个优化css的处理器,默认cssnano
        cssProcessor: require('cssnano'),
      
        cssProcessorPluginOptions: {
          preset: [  'default', {
              discardComments: { removeAll: true}, //对注释的处理
              normalizeUnicode: false // 建议false,否则在使用unicode-range的时候会产生乱码
          }]
        },
        canPrint: true  // 是否打印编译过程中的日志
      })
    ]
    

压缩之html文件的压缩

  • 安装:
  • 引入:
  • 配置:
    new htmlWebpackPlugin({
      template: path.join(__dirname, "./src/index.html"),
      filename: "index.html",
      minify: { //表示提供压缩选项
        removeComments: true, //移除页面的注释
        collapseWhitespace: true, //合并空白字符
        removeAttributeQuotes: true, //移除属性节点上的引号!
      }
    }),
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值