webpack--初试webpack( 核心、体验、资源打包)

前言

   webpack是当前前端项目中最常用的资源构建工具,从本文开始,来总结记录一下关于webpack的学习。

正文

  1、webpack简介

  webpack官网(https://webpack.docschina.org/

  我们代码中使用less,ES6的impot以及一些高级的语法,浏览器无法识别,因此webpack解决了这个问题,它是一种前端的资源构建工具,同时也是一个静态的模块打包器。在webpack看来,前端的所有资源文件(js/img/css/less)都会作为模块处理,他会根据模块的依赖关系进行静态分析,打包生成对应的静态资源。我的理解就是,要完成这些首先要告诉weback的一个入口起点,然后根据这些依赖关系,形成一个代码块,这个代码块就叫chunk,然后根据这个chunk进行不同的处理,这一过程叫打包,打包之后,输出出来的文件叫 bundles。

  2、webpack的五个核心概念

  (1)Entry

  入口,指示webpack以哪个文件为入口起点开始打包,但是打包之前需要分析清模块之间的依赖关系图。

  (2)Output

  输出,指示webpack 打包后的资源 bundles 输出到哪里,以及如何命名。

  (3)Loader

  Loader,指示webpack能够处理那些非 js 文件,可以理解 webpack 本身只能处理一些 js 文件,一旦处理样式文件,图片文件这些就会报错或处理不了。它就类似一个翻译官的角色。

  (4)Plugins

  插件,用于执行一些范围更广的任务,比如打包优化和压缩,一直到重新定义环境变量等。

  (5)Mode

  模式(process.env.NODE_ENV),development开发模式,能让代码在本地调试运行的环境。

                  production 生产模式,能让代码优化上线的运行环境。

  3、webpack 安装及初体验

  前提:node环境 npm安装成功

  全局安装:npm install -g webpack npm i -g webpack-cli

  本地安装:npm install webpack -D npm i webpack-cli -D

  注意:在安装webpack的时候,如果报错如下,是自己的项目名package.json中的name值设置成了webpack

  初体验,创建项目,通过 cmd 中输入 npm init 指令初始化项目,这里要注意 package.json 的 name 值问题,然后在本地安装依赖 npm i webpack-cli -D 和 npm install webpack -D ,创建src目录,在下面创建(index.js,index.css,data.json),index.js文件为项目入口文件,并分别测试css文件,json资源文件,代码如下:

 

  index.js

    // 普通js代码
    function add(x,y){
        return x + y
    }
    console.log(add(1,2));

    // json资源
    import data from "./data.json"
    console.log(data);

    // 引入css资源
    // import  "./index.css"

  index.css

    body{
        padding: 0;
        background-color: pink;
    }

  data.json

    {
       "name":"name",
       "age":18
    }

  分别测试下面的指令:

  开发环境指令:webpack ./src/index.js -o ./build --mode=development。以 ./src/index.js 为入口 ,./build 为输出,整体打包环境是开发环境。

  生产环境指令:webpack ./src/index.js -o ./build --mode=production。以 ./src/index.js 为入口 ,./build 为输出,整体打包环境是生产环境。

  经测试得出结论如下:

  (1)webpack能处理 js 资源,json 资源,不能处理 css 、html、和 img 资源,打包过程会报错:Module parse failed: Unexpected token (1:4)

  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

  (2)生产环境比开发环境多了压缩js代码,生产环境和开发环境将es6 模块编译成浏览器能识别的模块

  4.webpack打包样式资源

  (1)引入css样式资源-----css-loader 和 style-loader

  首先将index.js中的css引入代码注释放开

  命令行执行npm i style-loader css-loader -D 命令安装开发依赖

  在项目最外层创建webpack.config.js 文件,该文件为webpack配置文件,插入如下代码

// resolve用来拼接绝对路径的方法
const { resolve } = require("path");

module.exports = {
  //入口文件
  entry: "./src/index.js",
  // 输出
  output: {
    // 输出文件名
    filename: "build.js",
    // 输出路径
    // __dirname 是node.js的变量,代表当前文件的目录的绝对路径
    path: resolve(__dirname, "build"), // 代表输出到当前目录下创建的build文件夹下
  },
  // loader的配置
  module: {
    rules: [
      // 详细的loader配置
      {
        test: /\.css$/, //匹配.css结尾的文件
        use: [
          // 使用哪些loader进行处理,use数组中的执行顺序是从后往前
          //创建一个style标签,将js中的样式资源插入进去,添加到head中生效
          "style-loader",
          // 将css文件编程commonjs模块加载在js中,里面内容是样式字符串
          "css-loader",
        ],
      },
    ],
  },
  //plugin的配置
  //plugins: [],// 这里要注意,里面没有配置的时候要注释掉,否则会报错
  // 模式
  mode: "development", // 开发模式
  // mode:"production"// 生产模式
};

  然后执行命令 webpack即可,然后会发现控制台

   接下来需要,测试引入样式是否成功,需要在build文件下创建index.html文件,并在其中引入打包之后生成的build.js,然后再浏览器打开该html文件。

  (2)引入less样式资源-----less-loader

 

  按照css资源的方式,创建index.less文件,写入样式,然后在index.js中引入,再次执行wbepack命令,发现报错如下:

  上面的报错,是因为我们只配置了css样式的处理方式,没有在loader配置less的,注意:针对不同文件,需要配置不同的loader处理规则。因此需要配置less对应的解析的loader。webpack.config.js的loader.rules中添加如下代码:

    {
        test: /\.less$/, //匹配.less结尾的文件
        use: [
          "style-loader",
          "css-loader",
          "less-loader"// 将less文件变异成css文件
        ],
      },

  同样执行 webpack 命令

   测试less打包成功方法同css。

  5、webpack打包html文件----html-webpack-plugin

  前面解决了样式资源的打包,都用到了 loader 来处理,都需要下载依赖,然后在loader中配置,而处理htm资源,就需要用到 plugins,需要首先下载依赖,然后 webpack 引入,最后在 plugins 中配置,如下:

  同样创建 index.html 文件。

  首先,下载 html-webpack-plugin : npm i html-webpak-plugin -D

  然后webpack.config.js 中引入

const HtmlWebpackPlugin = require("html-webpack-plugin")

  最后在plugins中配置:

  //plugin的配置
  plugins: [
    new HtmlWebpackPlugin()
  ],

  我并没有在index.js中引入index.html文件,同样执行 webpack 命令,会发现,打包初了生成 build.js 的输出文件外,还生成了一个空的 html 文件,并且该 html 文件引入了生成的 build.js 文件,结论:new HtmlWebpackPlugin() 默认打包生成一个空的html 文件,该文件引入打包生成的所有资源文件。但是如果我们需要设置一个html 模板文件,就需要在new HtmlWebackPlugin() 方法中传入一个参数,参数为具体的模板文件路径,如下:

  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],

  这就相当于复制了index.html文件,并自动引入打包生成的所有资源文件。

  6、webpack打包图片资源----url-loader 和 file-loader

  由于在webpack对html文件进行打包的时候会使用我们设置的html模板,因此我们在html文件中引入img文件无法测试对图片资源的打包,所以这里需要通过样式资源引入的方法来测试打包图片资源。

  这里新建一个img文件夹,然后添加一张图片,在index.css文件中修改如下代码,并把css文件引入在index.js中

body{
    padding: 0;
    background-image: url(./img/webpack.jpg);
    background-repeat: repeat;
}

  然后安装依赖:npm i url-loader file-loader -D

  最后在webpack.config.js 中配置loader:

      // 这种方式无法处理html文件中的图片
      {
        test:/\.(jpg|png|gif)$/,
        loader:"url-loader",
        options:{
          // 图片大小小于8kb,会被解析为base64处理,优点减少请求数量减轻服务器压力,缺点是图片体积更大,文件请求速度更慢
          limit:8*1024
        }
      }

  执行webpack打包命令,发现打包成功。

   打包生成文件如下:发现图片的名字发生了变化(将图片修改成了对应的hash值)。

  上面的操作只解决了css文件中引入的img文件,但是实际开发我们想在html中引入图片怎么办,由于html模板中会原封不动的打包输出,而图片的打包会经过压缩修改名称处理,所以上面的方法就不适用。需要引入 html-loader 来负责引入img图片资源,从而交给 url-loader 处理。

  首先在html文件中写入

    <img src="./img/webpack1.jpg" alt="" />

  然后下载依赖: npm i html-loader -D

  然后在webpack.config.js 中的loader配置,如下:

      {
        test: /\.(jpg|png|gif)$/,
        loader: "url-loader",
        options: {
          // 图片大小小于8kb,会被解析为base64处理,优点减少请求数量减轻服务器压力,缺点是图片体积更大,文件请求速度更慢
          limit: 8 * 1024,
          esModule: false,
          // 这样可以修改图片名称,[hash:10]表示取hash值的前十位,[ext]表示原文件扩展名
          // name: "img/[hash:8].[name].[ext]",
        },
      },
      {
        // 因为url-loader默认适用了es6模块解析,而html-loader 引入图片适用commonJS处理,解析时会出现[object Module],需要关闭url-loader的es6模块化解析
        test: /\.html$/,
        // 处理html 文件的img文件
        loader: "html-loader",
      },

  然后执行webpack命令,打包成功

   对应的html文件中的img路径也发生了变化

  7、打包其他资源---- file-loader

  这里主要指其他不需要做任何优化之类的资源,这里以字体图标为例(https://www.iconfont.cn/),这里选择一个购物车图标,选择下载代码.,

  下载文件并解压,打开index.html文件,会有使用图标的方法介绍,这里使用Unicode 引用

  第一步:拷贝项目下面生成的 @font-face,代码中引入了(iconfont.ttf?t=1637326208397)

@font-face {
  font-family: 'iconfont';
  src: url('iconfont.ttf?t=1637326208397') format('truetype');
}

  第二步:定义使用 iconfont 的样式

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

   第三步:挑选相应图标并获取字体编码,应用于页面

<span class="iconfont">&#x33;</span>

  操作:首先在src文件下创建一个icont的文件夹,把下载的 iconfont.ttf 文件复制到文件夹下,然后把第一二步的代码复制到index.css文件,把第三步的代码复制到index.html 中,最后配置loader

    {// 打包其他资源(除了css,js,html资源以外的资源)
        exclude:/\.(css|js|html|less|json)$/,
        loader:"file-loader"
      }

  执行webpack命令打包结果如下:

  8、devServer

  我们前面测试打包是否成功,都是通过打包命令 webpak ,然后在生成的index.html 文件中测试,我们每次修改一行代码,都需要执行这个打包命令,这样开发就十分麻烦,不方便调试,因此,这节来学习devServe的功能和使用。

  devServer 开发服务器,用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)

  在webpack.config.js 中添加如下配置:

  devServer: {
      // 项目构建后的路径
    // contentBase: resolve(__dirname, "build"),// 这个配置在新版本的webpack中使用下面的方式配置,否则会报错
    static: { // static: ['assets']
      directory: resolve(__dirname, "build")
    },
    // 启用gzip压缩
    compress: true,
    // 端口号
    port: 3000,
    open:true// 自动打开浏览器
  },

  需要注意的是:devServer只会在内存中编译打包。不会有任何输出。

  启动devServer 的指令为:npx webpack-dev-server(本地启动),这里需要手动安装依赖 npm i webpack-dev-server -D

  之后执行npx webpack-dev-server 命令启动项目,发现webpack 并没有终止运行,还会继续运行

  然后通过 http://localhost:3000/ 就可以看编译的结果,然后我们修改开发的文件,发现会实时更新,不再需要手动执行webpack打包命令,更加便于开发使用

  注意:执行了webpack 打包命令,会输出编译之后的文件,执行webpack-dev-serve 并不会输出文件,只是在内存中编译的,没有任何输出。

  最后:以上代码源码请见 https://gitee.com/zaisy/webpack.git 的 webpack01 文件夹。

写在最后

  以上就是本文的全部内容,希望给读者带来些许的帮助和进步,方便的话点个关注,小白的成长之路会持续更新一些工作中常见的问题和技术点。

 

posted @ 2021-11-19 22:04  zaisy'Blog  阅读(525)  评论(0编辑  收藏  举报