webpack的基本使用2

一、webpack中的module、chunk和bundle的区别

webpack中的module、chunk和bundle的区别:css

  1. 对于一份同逻辑的代码,当咱们手写下一个一个的文件,它们不管是 ESM 仍是 commonJS 或是 AMD,他们都是 module ;
  2. 当咱们写的 module 源文件用 webpack 进行打包时,webpack 会根据文件引用关系生成 chunk 文件,webpack 会对这个 chunk 文件进行一些操做;
  3. webpack 处理好 chunk 文件后,最后会输出 bundle 文件,这个 bundle 文件包含了通过加载和编译的最终源文件,因此它能够直接在浏览器中运行。

module、chunk 和 bundle 其实就是同一份逻辑代码在不一样转换场景下的取了三个名字,咱们直接写出来的是 module,webpack 处理时是 chunk,最后生成浏览器能够直接运行的 bundle。html

通常来讲一个 chunk 对应一个 bundle,好比上图中的 utils.js -> chunks 1 -> utils.bundle.js;但咱们也能够用一些插件进行文件分离,好比说上图中,就用 MiniCssExtractPlugin 插件从 chunks 0 中抽离出了 index.bundle.css 文件。vue

参考:https://www.cnblogs.com/skychx/p/webpack-module-chunk-bundle.htmlnode

 

二、manifest

在使用 webpack 构建的典型应用程序或站点中,有三种主要的代码类型:react

  1. 你或你的团队编写的源码。
  2. 你的源码会依赖的任何第三方的 library 或 "vendor" 代码。
  3. webpack 的 runtime 和 manifest,管理全部模块的交互。

2.一、runtime和manifest

runtime 以及伴随的 manifest 数据,主要是指:在浏览器运行过程当中,webpack 用来链接模块化应用程序所需的全部代码。它包含:在模块交互时,链接模块所需的加载和解析逻辑。包括:已经加载到浏览器中的链接模块逻辑,以及还没有加载模块的延迟加载逻辑。webpack

webpack 和 webpack 插件是如何“知道”应该哪些文件生成的呢?答案是,webpack 经过 manifest,能够追踪全部模块到输出 bundle 之间的映射。在你的应用程序中,形如 index.html 文件、一些 bundle 和各类资源,都必须以某种方式加载和连接到应用程序,一旦被加载到浏览器中。在通过打包、压缩、为延迟加载而拆分为细小的 chunk 这些 webpack 优化 以后,你精心安排的 /src 目录的文件结构都已经再也不存在。因此 webpack 如何管理全部所需模块之间的交互呢?这就是 manifest 数据用途的由来。git

当 compiler 开始执行、解析和映射应用程序时,它会保留全部模块的详细要点。这个数据集合称为 "manifest",当完成打包并发送到浏览器时,runtime 会经过 manifest 来解析和加载模块。不管你选择哪一种 模块语法,那些 import 或 require 语句如今都已经转换为 __webpack_require__ 方法,此方法指向模块标识符(module identifier)。经过使用 manifest 中的数据,runtime 将可以检索这些标识符,找出每一个标识符背后对应的模块。es6

 经过使用内容散列(content hash)做为 bundle 文件的名称,这样在文件内容修改时,会计算出新的 hash,浏览器会使用新的名称加载文件,从而使缓存无效。一旦你开始这样作,你会当即注意到一些有趣的行为。即便某些内容明显没有修改,某些 hash 仍是会改变。这是由于,注入的 runtime 和 manifest 在每次构建后都会发生变化。github

 

三、Babel

Babel实际上是一个编译JavaScript的平台,它能够编译代码帮你达到如下目的:web

  • 让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器彻底支持;
  • 让你能使用基于JavaScript进行了拓展的语言,好比React的JSX;

3.一、Babel的安装与配置

Babel实际上是几个模块化的包,其核心功能位于称为babel-core的npm包中,webpack能够把其不一样的包整合在一块儿使用,对于每个你须要的功能或拓展,你都须要安装单独的包.

用得最多的是解析Es6的babel-preset-包和解析JSX的babel-preset-react包。

下面测试使用 babel 来解析支持 es6 和 react 语法。咱们先来一次性安装这些依赖包:

// npm一次性安装多个依赖模块,模块之间用空格隔开
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react

webpack中配置Babel的方法以下:

module.exports = {
    entry: __dirname + "/app/main.js",//已屡次说起的惟一入口文件
 output: { path: __dirname + "/public",//打包后的文件存放的地方 filename: "bundle.js"//打包后输出文件的文件名  }, devtool: 'eval-source-map', devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 historyApiFallback: true,//不跳转 inline: true//实时刷新  }, module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader", options: { presets: [ "env", "react" ] } }, exclude: /node_modules/ } ] } };

配置完以上选项后就能支持ES6以及JSX的语法了。测试:

npm install --save react react-dom
//Greeter,js
import React, {Component} from 'react'
import config from './config.json'; class Greeter extends Component{ render() { return ( <div> {config.greetText} </div>  ); } } export default Greeter
// main.js
import React from 'react';
import {render} from 'react-dom'; import Greeter from './Greeter'; render(<Greeter />, document.getElementById('root'));

直接编译或者在本地服务器上就能看到运行结果

3.二、.babelrc 文件

Babel其实能够彻底在 webpack.config.js 中进行配置,可是考虑到babel具备很是多的配置选项,在单一的webpack.config.js文件中进行配置每每使得这个文件显得太复杂,所以一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中。webpack会自动调用.babelrc里的babel配置选项

module.exports = {
    entry: __dirname + "/app/main.js",//已屡次说起的惟一入口文件
 output: { path: __dirname + "/public",//打包后的文件存放的地方 filename: "bundle.js"//打包后输出文件的文件名  }, devtool: 'eval-source-map', devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 historyApiFallback: true,//不跳转 inline: true//实时刷新  }, module: { rules: [ { test: /(\.jsx|\.js)$/, use: { loader: "babel-loader" }, exclude: /node_modules/ } ] } };
//.babelrc
{
  "presets": ["react", "env"] }

 

四、清理输出文件夹的文件(CleanWebpackPlugin)

因为以前的一些编译可能会致使用于输出的文件夹中包含了一些不必的文件,显得比较杂乱,咱们能够用clean-webpack-plugin 插件清理输出的文件夹中的文件。

该插件会在每次构建前清理输出文件夹,只会生成用到的文件。

npm install clean-webpack-plugin --save-dev
  const path = require('path');
  const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' }, plugins: [ new CleanWebpackPlugin(['public/*.*'], { root: __dirname, verbose: true, //开启在控制台输出信息 dry: false    }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };

4.一、webpack-dev-server和CleanWebpackPlugin同时使用的问题

有一个问题是当热加载和CleanWebpackPlugin插件同时使用时,运行dev-sever会从新编译,由此也从新使用清理插件,目标文件夹中的文件将被所有删除,可是此时并不生成新的文件。

虽然没报什么问题,代码也能够跑,可是仍是困惑了我好久。这个问题应该是运行webpack-dev-server时webpack会从新编译,由此使用了清理插件,可是dev-server并不会在工做目录中生成编译的文件,而是在内存中生成,因此看不到,可是代码跑的没问题。

要想解决这个问题,我在GitHub上看到了一个issue,可是尝试了好像会报错:https://github.com/johnagan/clean-webpack-plugin/issues/96。事后会继续关注该问题。

 

五、resolve(解析)

这些选项能设置模块如何被解析。

 

5.一、resolve.alias(配置模块路径别名)

在咱们引入一些模块文件时,可能文件路径层次比较深,这样的话就会致使相对路径的写法比较长。经过 resolve.alias 可以将一些路径配置成指定的别名,可以让咱们简写路径。

module.exports = {
  ...
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),  //由此引入src文件夹下的文件就能够写成:import xxx from @/xxx.js
    }
  },
}

 

5.二、resolve.extensions(指定文件扩展名)

经过指定 resolve 字段的extensions值能够指定自动解析的文件扩展名。

webpack的默认配置为:

module.exports = {
  //...
  resolve: {
    extensions: ['.wasm', '.mjs', '.js', '.json']
  }
};

由此用户在引入模块一些文件时就能够不带扩展,好比:

//引入 mian.js
import aaa from '../path/to/main';

若是咱们自定义该选项,就会覆盖默认数组即webpack的默认配置,这就意味着 webpack 将再也不尝试使用默认扩展来解析模块,对于须要指定自动解析的文件扩展名必须得写入该数组中。

 

5.三、resolve.modules

告诉 webpack 解析模块时应该去哪一个目录搜索该模块。

webpack的默认配置为:

module.exports = {
  //...
  resolve: {
    modules: ['node_modules']
  }
};

 

六、devServer配置

webpack-dev-server 可以用于快速开发应用程序。

 

6.一、devServer.proxy(服务器代理)

相关文章
相关标签/搜索