Webpack 是什么

  • 从本质上来讲, webpack 是一个现代的 javaScript 应用的静态 模块 打包工具。

模块

  • 在 ES6 之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。
  • 并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。
  • 而 webpack 其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系
  • 而目不仅仅是 Javascript.文件,我们的 CSS、图片、json 文件等等在 Webpack 中都可以被当做模块来使用

打包:

  • 就是将 项目中的各种资源模块进行打包合并成一个或多个包( Bundle).
  • 并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将 scs5 转成 css,将 ES6 语法转成 ES5 语法,将 Typescript 转成 Javascript 等等操作
  • 但是打包的操作似乎 grunt/gulp 也可以完成,它们有什么不同呢?

grunt/gulp 对比

  1. grunt/gulp 的核心是 Task
  2. 我们可以配置一系列的 task,并且定义 task 要处理的事务(例如 ES6、ts 转化,图片压缩, scss 转成 css)
  3. 之后让 grunt//gulp 来依次执行这些 task,而且让整个流程自动化。

所以 grunt/gulp 也被称为前端自动化任务管理工具

什么时候用 grunt/gulp 呢

  • 如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。
  • 只需要进行简单的合并、压缩,就使用 grunt/gulp 即可。
  • 但是如果整个项目使用了模块化管理,而且相互依赖非常强,就可以使用更加强大的 webpack 了。

grunt/gulp 对比 Webpack

  • grunt/gulp 更加强调的是前命令的自动化,模块化不是它的核心
  • webpack 更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。

webpack 安装

webpack 的运行依赖于 node 环境, 使用 npm 安装

webpack 起步

项目目录:目录演示

webpack 会将所有入口文件 main.js 定义的各种依赖包括自身,按照配置文件的规则打包进 dist 文件中

main.js 入口文件:

// 定义了各种需要被导入的模块(文件
let { add } = require("./js/Common")
import { age, uname } from "./js/es6modules"

console.log(uname)

console.log(add(age, age, age))

// 依赖css 文件
require('./css/base.css')

// 依赖less 文件
require('./css/special.less')

webpack.config.js

webpack 配置文件定义了程序入口,和出口

// 导入一个包, path 为 nodejs的自带包
const path = require('path')

module.exports = {
  // 入口
  entry: './src/main.js',
  output: {
    // path必须为 绝对路径
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
}

Tips: 有了此配置文件后就可以以直接使用命令webpack,让 全局的 webpack进行项目的打包。

package.json

node 的当前项目配置, npm init 生成

// 注意json文件不允许 注释,此处仅为演示
{
  "name": "webpackone",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    // 定义了一个命令(脚本),名为 build
    "build": "webpack"
  },
  "author": "",
  "license": "ISC",
  // 开发时依赖包
  "devDependencies": {
    // npm install PackageName --save-dev 生成
    "webpack": "^5.14.0",
    "webpack-cli": "^4.3.1"
  },
  // 运行时依赖??
  "dependencies": {}
}

执行自定义命令 build:npm run build 的作用约等同于直接在命令行执行webpack 但不同的是,会优先使用当前项目内的 webpack. (相当于一个 python 虚拟环境)

Tips: devDependencies 开发时安装依赖模块,里面包含了当前项目内通过 npm 安装的包名及其版本

loader

在开发中不仅仅有基本的代码处理,也需要加载 css、图片,也包括一些高级的将 ES6 转成 ES5 代码,将 Typescript 转成 ES5 代码,将 scss、les 转成 ss,将 jsx、,vue 文件转成 s 文件等等. 对于 webpack 本身的能力来说,对于这些转化是不支持的. 需要给 webpack 扩展对应的 loader

使用:

  1. 通过 npm 安装需要使用的 loader
  2. 在 webpack.config.js 中的 modules 关键字下进行配置

大部分 Loader 我们都可以在 webpack 的官网中找到,并且学习对应的用法。

安装 css-loader:

css-loader 解释(interpret) @import 和 url() ,会在 import/require() 后再解析(resolve)它们。

npm install css-loader --save-dev 

配置:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        // 使用多个 loader时的执行顺序从右向左的
        use: ['style-loader', 'css-loader']
      }
    ]
  }
}

一个安装了 css,less,file,url,的完整配置代码

const path = require("path")

module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    // 配置此项,以后涉及url时 路劲都会生成为相对同时加上前缀 dist/
    publicPath: "dist/",
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        // 使用多个 loader时的执行顺序从右向左的
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: "style-loader", // creates style nodes from JS strings
          },
          {
            loader: "css-loader", // translates CSS into CommonJS
          },
          {
            loader: "less-loader", // compiles Less to CSS
          },
        ],
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              // 将 导入图片小于 limit是会转为 base64 格式
              // 将 导入图片大于是 需要使用插件 file-loader 作为此插件的补充
              limit: 8192,
              // 原打包图片的名字 是一个哈希值,现希望为: 
              name: "img/[name].[hash:8].[ext]",
              // (ext-> extension)
            },
          },
        ],
      },      
    ],
  },
}

Tips: webpack 会处理各种依赖所以,项目导入的各种文件他们的导入也都需要安装相应的 loader

// main.js
// 依赖css 文件
require('./css/base.css')

// 依赖less 文件
require('./css/special.less')
/* css/base.css */
body {
  /* 此时导入的图片文件也需要作为模块导入相应的loader  url-loader */
  background: url(../img/9353cb.jpg);
}

plugin 插件

webpack 中的插件,就是对 webpack 现有功能的各种扩展,比如打包优化,文件压缩等等。

loader 和 plugin 区别:

  • loader 主要用于转换某些类型的模块,它是一个转换器。
  • plugin 是插件,它是对 webpack 本身的扩展,是一个扩展器

plugin 的使用过程:

  1. 通过 npm 安装需要使用的 plugins(某些 webpack 已经内置的插件不需要安装
  2. 在 webpack.config.js 中的 plugins 中配置插件。

BannerPlugin

  • 一个最简单的插件,为打包的出口文件添加版权声明(现在是单独生成一个 license 文件)。 webpack 自带
// webpack.config.js
const webpack = require('webpack')

module.exports = {
  // ...
  plugins: [
      // 版权信息
      new webpack.BannerPlugin('最终解释权归国家所有'),
      // Vue-loader请确保引入这个插件!
      new VueLoaderPlugin()
    ],
}

webpack-htmlWebpackPlugin

目前,我们的 index. htm 文件是存放在顶目的根目录下的。

在真实发布项目时,发的是 dist 文件夹中的内容,但是 dist 文件夹中如果没有 index.html 文件,那么打包的 js 等文件也就没有意义了。

所以,我们需要将 index.htm 文件打包到 dist 文件夹中,这个时候就可以使用 Htmlwebpackplugin 插件

这个插件可以为我们做这些事情:

  • 自动生成一个 index.html 文件(可以指定模板来生成
  • 将打包的 js 文件,自动通过 script 标签插入到 body 中

安装:

npm install html-webpack-plugin --save-dev

配置:

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    // 配置此项,以后涉及url时 路劲都会生成为相对同时加上前缀 dist/
    // 此时直接使用 dist里面的文件,不再需要加上路劲 ./dist/
    // publicPath: "dist/",
  },
  // ...
  plugins: [
      new HtmlWebpackPlugin({
      template: 'index.html',
    }),
    ],
}
  • 这里的 template:表示根据什么模板来生成 index.html
<!-- /index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>title</title>
  </head>
  <body>
    <div id="app"></div>

    <!-- 生成的index文件,会自动添加依赖项 -->
    <!-- <script src="./dist/bundle.js"></script> -->
  </body>
</html>

uglifyjs-webpack-plugin

  • 项目发布之前,我们必然需要 s 等文件进行压缩处理

目前版本的 webpack 已经会自动对代码进行丑化。5.14.0

webpack-dev-server 本地服务器

webpack 提供了一个可选的本地开发服务器,这个本地服务器基于 nodejs 搭建,内部使用 express 框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。

安装:

npm install --save-dev webpack-dev-server

配置:

// webpack.config.js
module.exports = {
  // ...
  devServer: {
      contentBase: './dist',
      inline: true,
    }
}

devserver 也是作为 webpack 中的一个选项,选项本身可以设置如下属性:

  • contentbase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写。/dist
  • port:端口号
  • inline:页面实时刷新
  • historyapifallback:在 SPA 页面中,依赖 HTML5 的 history 模式

启动 server

命令:webpack-dev-server, 命令行中并没有此命令, 需要配置本项目下 node 配置文件中的"scripts"

// package.json nodeJs配置
{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "dev": "webpack serve --open"
  },
}
  • 启动服务: npm run dev

此时更改相关文件会自动刷新,并引用更改。但是更改的更新储存是在 缓存中的,并没有在本地文件中进行实时的更新。所以服务停止后需要进行打包生成 npm run build

在 webpack 中文文档( https://www.webpackjs.com/)配置是 "start": "webpack-dev-server --open" 对现版本而言 错误。上面配置参照官网而来。查资料优先考虑官网。( @3.11.2 )

抽离 webpack 配置文件

现在的 webpack 配置是全部混为一体的,而实际上线时有些配置是没有必要。这时就需要对 webpack 的配置文件进行一个 分离。

1 安装依赖插件:

npm install webpack-merge --save-dev

webpack-merge 提供了 merge 连接数组并合并对象以创建新对象的功能。如果遇到函数,它将执行它们,通过算法运行结果,然后将返回的值再次包装在函数中。

2 将源配置文件分离为 3 个配置文件: base.config.js, dev.config.js, prod.config.js 分别定义不同的配置,在不同的环境下使用

// base.config.js 相同的配置,主配置
module.exports = {
  entry: "./src/main.js",
  output: {
    // 注意这里生成的位置路劲与之前有所不同,因为 dist的生成是基于当前配置文件目录的
    path: path.resolve(__dirname, "../dist"),
    filename: "bundle.js",
  },
  module: {},
  plugins: [],
  resolve: {},
}

// dev.config.js, 开发时配置

const {merge} = require("webpack-merge")
// 引用定义的相同配置,合并成一个新的配置返回给使用者使用
const baseConfig = require("./webpack.base.config")

module.exports = merge(baseConfig, {
  // webpack-dev-server
  devServer: {
    contentBase: './dist',
    inline: true,
  }
})

webpack-merge 我的理解,将第二个参数按照一定算法合并。

3 同时因为有了这三个配置文件不再需要,之前的默认配置文件了。这时就需要更改 nodejs 的当前项目配置了

// package.json
{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config ./build/webpack.prod.config.js",
    "dev": "webpack serve --open --config ./build/webpack.dev.config.js"
  },
}

对于不同的命令使用了不同的配置文件,因为不再需要之前的默认配置文件了,需要手动指定配置 path --config path


完, Vue 推荐使用 Vue CLI 直接创建一个项目的脚手架。而非是像这样自己配置。

嗯,这里有一个可能不完全手动配置 webpack 于 Vue,没有手动测试,仅供参考


相关推荐:

来自系列:Vue 笔记

分类 前端下文章:

微信小程序开发 days1 关注点:文件结构,json配置文件, 模板语法

小程序开发学习笔记 days2。 关注点:view, text, rich-text, button, image, navigator, icon, swiper, radio, checkbox

小程序学习笔记 days3。 关注点:生命周期,自定义组件

小程序学习笔记 days4。 关注点:scroll-view, Promise

css3 选择器,背景定义(定位), 盒子定位,弹性布局,栅格系统。还有一些常用的 css 属性。

更多...

评论([[comments.sum]])

发表

加载更多([[item.son.length-2]])...

发表

2020-11 By chuan.

Python-flask & bootstrap-flask

图片外链来自:fghrsh

互联网ICP备案号:蜀ICP备2020031846号