webpack

Posted 用心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack相关的知识,希望对你有一定的参考价值。

一、webpack

官网:https://webpack.js.org

1.1、webpack是什么?

webpack是一种前端资源构建工具,一个静态模块打包器.在webpack看来,前端的所有资源文件(js/json/css/image/less/sass...)都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源。webpack可以解决当前web开发中所面临的困境,

webpack提供了:

  • 友好的模块化支持
  • 代码压缩混淆
  • 处理js/css兼容问题
  • 性能优化

目前绝大多数企业中的前端项目,都是基于webpack进行打包构建的(vue/react)。

从 v4.0.0 开始,webpack 可以不用再引入一个配置文件来打包项目,然而,它仍然有着高度可配置性,可以很好满足你的需求。
默认配置文件:webpack.config.jswebpackfile.js

1.2、webpack五个核心概念

  • entry入口

本项目应该使用哪个模块,来作为构建其内部依赖图的开始(指定打包入口文件)

  • output输出

在哪里输出它所创建的 bundle,以及如何命名这些文件,默认值为 ./dist

  • mode 模式

通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

  • loader 加载器

loader让webpack能够去处理那些非js文件(webpack自身只理解js)

  • plugin

插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

1.3、安装webpack

安装方式2种

  1. 全局安装
    npm i -g webpack@4 webpack-cli@3
  2. 局部安装 (推荐)
    webpack是运行在node环境中的,Node >= 8.10 和 npm >= 5.6
npm init -y
npm i -D webpack@4 webpack-cli@3 
# webpack 打包使用的核心代码
# webpack-cli 打包使用时的命令

安装好后可以通过先前提及过的npx命令来检查webpack的版本以确定是否安装成功:
npx webpack --version
在package.json文件中配置webpack运行脚本命令

"scripts": {
  "dev": "webpack"
 },

1.4、webpack基本使用

在项目根目录下面创建一个webpack.config.js文件,此文件是webpack的默认配置文件名称,后续就可以在此目录下面对webpack进行运行打包配置。模块化规范 commonjs

const path = require(\'path\')

module.exports = {
  # 打包模式  development |  production
  mode: \'development\',

  # 开发工具配置
  // 开发时配置 source-map ,生产环境要关闭
  // 作用:代码出错了,可以帮我们定位到src目录中程序
  devtool: \'source-map\',

  # 项目入口
  entry: \'./src/index.js\',
   ## 对象 多入口
  // entry:{\'main\': \'./src/main.js\'} 
  // key对应打包生成后的文件名称,或路径  value入口文件
   ## 数组 合并
  // entry:[\'./src/index.js\', \'./src/main.js\']

  # 项目出口
  output: {
    // 打包生成的文件路径,路径一定要用绝对路径
    path: path.resolve(__dirname, \'dist\'),
    // 打包生成后的主入口js文件
    filename: \'js/[name].js\'
    // [name]默认的名称为main,如果你的entry为对象方式,则name为key值.
    // filename: \'[name].[hash:8].js\'
    // [hash]随机生成21位字符串,支持截取[hash:截取的长度]
  }
}

1.5、配置访问入口模板文件

在项目根目录下面创建一个public目录,并在此目录中创建一个index.html文件,使用webpack的 html-webpack-plugin 插件,可以将此文件用于项目web入口文件模块

# 安装
npm i -D html-webpack-plugin@4
# 引入
// webpack插件,帮助webpack打包生成时,创建一个index.html文件
const HtmlWebpackPlugin = require(\'html-webpack-plugin\')
// 删除打包成的dist目录
const {ClearWebpackPlugin} = require(\'clean-webpack-plugin\')
# 使用 webpack.config.js
plugins: [
  new HtmlWebpackPlugin(),
  new HtmlWebpackPlugin({
      // 模板
    template: path.resolve(__dirname, \'public/index.html\'),
  })
]

1.6、devServer创建

我们已经可以使用打包工具去将写好的代码进行打包了,但是在操作的过程中大家可能会发现有一个比较麻烦的地方:修改一次代码就得重新打包一次,那么有没有在开发阶段,编写代码后自动进行编译看效果并且最好还能提供web服务的功能呢?,答案是有的,它就是webpack-dev-server自动化打包工具。

# 安装 webpack-dev-server
npm i -D webpack-dev-server@3
# 配置 node环境 web环境
// 开发环境服务配置打包时,放在内存中,不会在磁盘中生成一个dist目录
devServer: {
    // 运行代码目录
    contentBase: path.resolve(__dirname, \'dist\'),
    // 打包进度
    progress: true,
    # 端口号 
    port: 8080,
    // 域名
    host: \'localhost\',
    // 自动打开浏览器
    open: true,
    // 安静模式,除了一些基本的启动信息以外,其他的内容都不要显示
    quiet: true,
    // 服务器代理 --> 解决开发环境跨域问题
    proxy: {
      // 一旦devServer服务器接受到 /api开头的请求,就会把请求转发到另一个服务器
      \'/api\': {
        target: \'http://localhost:3000\',
        // 发送请求时,请求路径重写: 将/api 去除
        pathRewrite: {
          \'^/api\': \'\'
        }
      }
    }
}
# package.json中的scripts中配置命令
"serve": "webpack-dev-server"

前端路由模式有2种,

1、hash模式,锚点http://xxx.com/#/aaa

//事件触听监听hash变化
window.onhashchange = function (){
    console.log(getHash());
}
window.onload = function (){
    console.log(getHash());
}
//得到当前的地址栏中的hash值
function getHash(){
let urlHash = (location.hash = \'\' | location.hash = \'#/\') ? \'#/login\' : location.hash
return urlHash.slice(2)
}

2、h5提供history模式,它和正常的路由一样的,但是它默认不刷新,需要web服务器支持

1.7、加载器

1.7.1、加载器概述

在实际开发中,webpack只能打包处理以.js为后缀的模块,其他非.js后缀的模块webpack默认处理不了,而需要调用loader加载器才能正常打包,否则会报错!

loader加载器可以协助webpack打包处理特定的文件模块了,例如:

  • sass-loader可以打包处理.scss相关的文件
  • css-loader可以处理css样关的文件
  • babel可以处理js兼容模块
  • 配置图片处理 …

1.7.2、打包处理css文件

正如前面所说,webpack默认不能打包css文件,如果在没有安装css加载器的时候打包,包含css文件的项目则会报错:

我们需要安装一个CSS的加载器才能让webpack帮助我们打包css文件。

所以要想打包css文件,则需要安装css加载器,该加载器的安装命令为:

npm i -D style-loader css-loader

安装好需要的加载器后需要对webpack进行配置,告诉webpack当遇到css后缀的文件应该交由哪个加载器去处理。在webpack打包命令对应的module的rules数组中添加css-loader规则:

// 加载器
module: {
  // 规则
  rules: [{ 
      // 正则匹配loader解析文件扩展名
      test: /\\.css$/, 
      // loader执行顺序
      // 执行顺序 写在一行:从右向左,写在多行:从下向上执行
      use: [
          "style-loader", 
          "css-loader"
      ] 
  }],
}

在写加载器use的时候,需要注意:
- use数组中指定的加载器顺序是固定的
- 多个加载器调用的顺序是:从右向左、从下往上调用(倒序执行)
在配置好对应的css加载器后,webpack才能打包对应的css文件

1.7.3、打包处理scss文件

# 安装css预处理loader
npm i -D sass-loader@10 node-sass@5 style-loader css-loader
# loader配置
module: {
  rules: [
    // scss处理
    {
      test: /\\.scss$/,
      // 执行顺序   从右到边,从下到上  
      use: [
        "style-loader",
        "css-loader",
        "sass-loader"
      ]
    }
  ]
}

1.8、配置图片处理

# 安装
npm i -D url-loader file-loader html-loader@1
# loader配置
module: {
  rules: [
    // 图片处理
    {
      test: /\\.(png|jpeg|jpg|gif)$/i,
      use: [
        {
          loader: \'url-loader\',
          options: {
            // 图片小于8kb,就会被base64处理
            // 优点: 减少请求数量(减轻服务器压力)
            // 缺点:图片体积会更大(文件请求速度更慢)
            limit: 8 * 1024,
            // 打包后的路径和文件名称 [ext]扩展名
            name: \'img/[name].[ext]\',
            // 打包后的文件指定访问路径前缀
            publicPath: \'/\'
          }
        }
      ]
    },
    {
      test: /\\.html$/,
      // 处理html中的img(负责引入img,从而能被url-loader进行处理)
      loader: [\'html-loader\']
    }
  ]
}

 1.9、处理静态资源

像项目中字体资源是不需要进行打包处理的,可以直接的通过复制方式给打包到目标目录中

# 安装
npm i -D copy-webpack-plugin@6
# 引入
const CopyPlugin = require(\'copy-webpack-plugin\')

# plugins配置
plugins: [
  // 复制静态资源
  new CopyPlugin({
    patterns: [
      {
        // 来源
        from: path.resolve(__dirname, \'./src/iconfont/\'),
        // 目标
        to: path.resolve(__dirname, \'./dist/iconfont\')
      }
    ]
  })
]

1.10、js兼容处理

webpack在不需要引入任何loader可以对于js进行打包处理,但是它不会对于js兼容性进行任何的处理,而我们编写的项目是需要在不同的浏览器中运行的,此时就需要对于js的兼容性在打包过程中进行对应的处理。使用babe1来完成对应的js兼容处理

# 按需加载进行兼容性处理
npm i -D babel-loader @babel/core @babel/preset-env core-js
# loader配置
module: {
  rules: [
      // js兼容处理
      {
        test: /\\.js$/,
        // 排除
        exclude: /node_modules/,
        use: [
          {
            loader: \'babel-loader\',
            options: {
              presets: [
                [
                  \'@babel/preset-env\',
                  {
                    // 按需加载
                    useBuiltIns: \'usage\',
                    // 指定core-js版本
                    corejs: 3,
                    // 兼容性做到哪个版本的浏览器
                    targets: {
                      chrome: \'50\',
                      firefox: \'50\',
                      ie: \'9\',
                      safari: \'10\',
                      edge: \'17\'
                    }
                  }
                ]
              ]
            }
          }
        ]
      }
  ]
}

1.11、art-template集成

npm i -D art-template art-template-loader
module.exports = {
  module: {
    rules: [
      {
        test: /\\.art$/,
        loader: "art-template-loader"
      }
    ]
  }
}

# 注:对于babel处理js,它有兼容问题,可以选择对于js更高版本处理,或者可以处理

1.12、externals忽略不打入的包

例如项目中使用从 CDN 引入 jQuery,而不是把它打包进来使用

import $ from \'jquery\'

# webpack.config.js
externals: {
  // jquery: \'jQuery\'
  // import中的导入的包名称,window对象中的名称
  jquery: \'$\'
}

1.13、路径别名与导入后缀省略

  // 解析模块的规则
  resolve: {
    // 配置解析模块路径别名:优点简写路径,缺点路径没有提示
    alias: {
      // 定义一个@变量,可在import引入时使用
      \'@\': path.resolve(__dirname, \'./src\')
    },
    // 配置省略文件路径的后缀名称 import \'@/index\'
    // 如果省略,建议文件名称不要重名了
    extensions: [\'.js\',\'.json\',\'.art\']
  }

以上是关于webpack的主要内容,如果未能解决你的问题,请参考以下文章

Vue报错:Uncaught TypeError: Cannot assign to read only property 'exports' of object 的解决方法(代码片段

如何使用webpack加载库源映射?

浅析 -- webpack

报错:✘ http://eslint.org/docs/rules/indent Expected indentation of 0 s paces but found 2(代码片段

报错:✘ http://eslint.org/docs/rules/indent Expected indentation of 0 s paces but found 2(代码片段

无法创建中继容器; graphql.js 文件似乎有 webpack 工件?