【打包工具】Webpack-1

567 阅读4分钟

概念

webpack是一个模块打包工具,由于前端大量地采用模块化开发,所以模块打包工具应运而生,诸如parcel、webpack等都是时下流行的优秀的打包工具。

模块打包,通俗地说就是:找出模块之间的依赖关系,按照一定的规则把这些模块组织合并为一个JavaScript文件。

Webpack认为一切都是模块,JS文件、CSS文件、jpg/png图片等等都是模块。Webpack会把所有的这些模块都合并为一个JS文件,这是它最本质的工作。当然,我们可能并不想要它把这些合并成一个JS文件,这个时候我们可以通过一些规则或工具来改变它。

入口entry

这个就是设置webpack入口的起点,webpack会根据这个入口来查找到对应的依赖模块 我们可以在webpack.config.js中配置这个入口文件

module.exports = {
  entry: './path/to/my/entry/file.js'
};

出口output

这里是用来设置输出文件的文件名或者是输出文件的位置。它会创建一个bundles,默认是./dist,基本上,所有内容都会被输出到这个文件夹中。同样我们可以在webpack.config.js中配置

const path = require('path'); //node.js的模块,用于操作文件路径

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),//设置`dist`文件夹
    filename: 'my-first-webpack.bundle.js'//文件名
  }
};

loader

webpack是认识javascript的,但是它不认得css跟html或者其他文件,所以我们就通过这个来设置让webpack知道对应的处理方式,并转换成对应的模块

我们需要设置两个东西,一个是test属性,就是让webpack知道要处理啥类型的文件,还一个是use属性,就是让webpack知道用什么loader处理

const path = require('path');

const config = {
  output: {
    filename: 'my-first-webpack.bundle.js'//输出文件名
  },
  module: {
    rules: [
      { test: /\.txt$/, use: 'raw-loader' }//遇到.txt时用raw-loader处理一下
    ]
  }
};

module.exports = config;

上面在rules上面设置了一个数组,意思是,当webpack在处理时发现.txt的路径,就使用raw-loader来处理一下再打包

模式

我们可以选择开发者模式,或者选择生产模式,两者几乎没有实际区别,但是一般来说,生产模式要比开发者模式压缩一些,而且需要设置浏览器缓存。当然这都取决于我们怎样设置。

module.exports = {
  mode: 'production'//生产模式,压缩版
};
module.exports = {
  mode: 'development'//开发者模式,会有注释等信息
};

安装

在这里不推荐使用全局安装

mkdir webpack //创建一个目录webpack
cd webpack
yarn init -y
yarn add webpack webpack-cli --dev

上面我们初始化yarn后,使用yarn来add了webpack跟webpack-cli(webpack的命令行工具)

这时候会发现多了node_modules和package.json与yarn.lock三个文件

根据官方文档,我们还需要调整package.json 文件,以便确保我们安装包是私有的(private),并且移除 main 入口。这可以防止意外发布代码。

练习导出js文件

mkdir src && cd src &&touch index.html index.js index.css 我们新建一个目录webpack并在终端内执行上面这段代码就可以创建src目录,并创建html、css、js文件

配置文件

新建webpack.config.js,并且写入代码

    const path = require('path');

    module.exports = {
      mode: 'development',//开发者模式
      entry: './src/index.js',//进入src,找到index.js文件
      output: {
        filename: 'bundle.js', //输出文件名为bundle.js
        path: path.resolve(__dirname, 'dist')//输出目录名为dist
      }
    };

运行

由于我们是在创建的目录内安装了webpack,所以我们需要运行webpack的话就需要运行./node_modules/.bin/webpack

不过有更简单的方法 npx webpack --version 查看版本

npx webpack 运行webpack

浏览器缓存机制

由于浏览器缓存机制的存在,我们的后端可以在httpHeader中设置让浏览器缓存,这样在不修改网页原文件时,用户就可以通过浏览器缓存,当第二次进入网页时,浏览器缓存就会读取缓存中的文件,提高刷新网页的效率。

浏览器缓存机制主要识别文件名,如果我们在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。也就是说,如果我们使用发布的文件名都是bundle.js,当我们设置了浏览器缓存时,即使修改了bundle.js很有可能浏览器会以为我们没有修改过js文件,所以读取的依然是旧版本的文件。

那么只要我们修改了bundle中的文件名,这样浏览器不就知道我们修改过js或者css文件了吗?

这里需要注意,我们不能设置index.html的缓存,因为index.html是入口,浏览器通过这个入口来识别我们是否更新了css或者js文件,如果对首页做了缓存,那么浏览器一直加载缓存中的首页。

现在我们需要一个不同名的机制,那么webpack也可以帮我们做,那就是在output对象中设置。

设置output输出文件的名称

使用入口名称:

filename: "[name].bundle.js"

使用内部 chunk id

filename: "[id].bundle.js"

使用每次构建过程中,唯一的 hash 生成

filename: "[name].[hash].bundle.js"

使用基于每个 chunk 内容的 hash

filename: "[chunkhash].bundle.js"

长期缓存机制下生成hash filename: '[name].[contenthash].html'

长期缓存机制下生成hash这个一般来说是我们喜欢用的,它会在内部进行hash运算,生成一串hash码,然后跟我们的输出文件名做拼接

清理dist以及优化运行指令

由于我们output的文件名不同,所以我们需要在运行webpack之前删除原先的dist文件,否则会越积累越多。

我们可以在package.json中的script内设置

"scripts": {
    "build": "rm -rf dist && npx webpack"
  },

它的含义是我以后可以通过yarn build来先删掉dist再执行npx webpack这个cli命令

练习导出html文件

我们需要安装html插件,并且调整webpack.config.js文件

yarn add html-webpack-plugin --dev

上面代码新增了一个html插件plugin

webpack.config.js设置为

const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'development',
    entry: './src/index.js',
    output: {
        filename: '[name].[contenthash].js',
        path: path.resolve(__dirname, 'dist')
    },
   + plugins: [
     +   new HtmlWebpackPlugin({
      +      title: 'Output Management'
       + })
    +]
};

这时候运行yarn build后发现dist中会有index.html。

上面的代码中title是什么?打开dist/index.html就知道了,可以通过设置这个来将dist文件中的title做修改。

但是这时候的index.html跟我自己创建的在src内的index.html无关,如果我想用让它按照我给的index.html来生成应该怎么做呢?

我们在new HtmlWebpackPlugin内写入以下代码

new HtmlWebpackPlugin({
      template: 'src/index.html'
    })

这样就可以使用我们自己写的html来打包了

练习导出css

我们可以使用两种方式来处理css类型。一种是使用css-loader,另外一种就是使用css plugin。

使用css-loader方式

webpack.config.js文件中设置

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ]
      }
    ]
  }
}

然后安装

yarn add style-loader --dev
yarn add css-loader --dev

这时候使用http-server或者使用webpack自带的server来查看生成的html,就会发现css被插入index.html里。

使用plugin插件加载css

使用这种方式跟css-loader方式不同的是,它会在新生成的dist文件夹中生出css文件,并且帮助调整好引用。这样是一种css样式与js文件分离的方法,能够提高加载速度

css-loader是直接加载到js的bundle中,再写入页面里。可以理解是直接写到页面的style中。

下载

yarn add mini-css-extract-plugin --dev

用法:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // 类似于 webpackOptions.output 中的选项
      // 所有选项都是可选的
       filename: '[name].[contenthash].css',
            chunkFilename: '[id].[contenthash].css',
      ignoreOrder: false, // 忽略有关顺序冲突的警告
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // 你可以在这里指定特定的 publicPath
              // 默认情况下使用 webpackOptions.output 中的 publicPath
              publicPath: '../',
              hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

webpack-dev-server

这个是一个开发工具,能够帮我们快速开发,就跟http-server一样,但是它更加强大

安装

yarn add webpack-dev-server --dev

配置

1、首先我们需要将mode修改成 mode: 'development',

2、在pageage.json中写:

"start": "webpack-dev-server --open",

上面这样配置就可以使用yarn start来快速打开

3、在webpack.config.js中写

module.exports = {
+ devtool: 'inline-source-map',//这个设置可以让我们很快知道被打包后的文件哪个位置出错了
+ devServer: {
+     contentBase: './dist',
+   },
}

上面代码是告诉webpack-server将 dist 目录下的文件 serve 到 localhost:8080 下。serve的意思是将资源作为 server 的可访问文件

如果我们更改任何源文件并保存它们,web server 将在编译代码后自动重新加载。而且此时删除了dist文件夹,server依然存在。

根据模式选择不同命令

在生产模式下,我们需要浏览器缓存,所以需要使用yarn build命令来构建dist文件包,但是当我们开发时,我们只需要yarn start来查看页面就可以了,所以我们需要配置两种模式的config.js文件

  • 创建webpack.config.prod.js,放生产模式下的代码
  • 默认的webpack.config.js为开发模式
  • 修改pageage.json文件

开发模式跟生产模式的不同点:

开发模式下我们需要css loader跟webpack server

生产模式下我们需要css plugin,不需要webpack server

所以我们把代码整合一下即可,这里就不贴整合后的代码了,请访问github查看

这里贴一下设置的package.json的配置

"build": "rm -rf dist && npx webpack --config webpack.config.prod.js"

使用--config webpack.config.prod.js来让这个命令行找到对应的config.js文件再进行处理

参考文档

webpack中文:www.webpackjs.com/concepts/

html插件:www.webpackjs.com/plugins/htm…

html插件配置:github.com/jantimon/ht…

css插件:webpack.js.org/plugins/min…

css loader:www.webpackjs.com/loaders/css…

DevServer:webpack.docschina.org/guides/deve…

配置文件:webpack.docschina.org/configurati…