webpack基础配置

webpack的基础配置已经学习过无数遍,每次都是学完就忘,这次决定记录下来,把自己学习的过程记录下来,一是为了加强记忆,二是为了以后方便回顾。

背景

webpack是一款目前来说应用特别广泛的打包工具,也是提升前端开发level的一个重要技能。本篇主要探讨下webpack的入口、输出等,比较基础如果已经非常熟悉webpack了 可不必细读也可绕道。

概念

官网的定义:(官网地址)

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。

webpack是一个静态模块打包器,所谓的静态模块,包括脚本、样式表和图片等等。它所做的事情是:分析项目结构,根据资源引用构建出一个依赖关系图,然后再将模块划分打包出一个或多个bundle。
webpack基础配置_第1张图片
先理解webpack的四个核心概念

  • 入口entry:指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
  • 输出output:在哪里输出它所创建的bundles,以及如何命名这些文件,默认值为 ./dist。
  • loader:处理那些非 JavaScript 文件(webpack自身只理解 JavaScript)
  • 插件(plugins):用于执行范围更广的任务

基本安装

先在全局安装webpack

npm install webpack webpack-cli –g

打包一个bundle.js

webpack v4.0.0 开始,可以不用引入一个配置文件,直接通过命令行创建,这里的entry和output就对应了上述概念中的入口和输入。

webpack <entry> [<entry>] -o <output>

举个栗子
原文件

// demo1/index.js
console.log('hello webpack')

打包

webpack index.js -o dist/bundle.js

最后生成的目录
webpack基础配置_第2张图片
我们也可以在项目目录新建一个html引入打包后的bundle.js文件查看效果。

配置文件

上面演示了命令行打包的方式,然而实际项目都比较复杂需要很多配置,所以我们尝试下用配置文件来打包。

配置

配置文件的命令如下

webpack [--config webpack.config.js]

项目结构

webpack-demo/demo2
  |- package.json
  |- webpack.config.js
  |- /dist
    |- index.html
  |- /src
    |- index.js

webpack.config.js

const path = require('path');
// 通过module.exports导出一个配置对象,还可以导出为一个函数或者是Promise 有兴趣可以自己去了解
module.exports = {
     
  entry: './src/index.js',
  output: {
     
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
};

运行

webpack --config webpack.config.js

打包结果
webpack基础配置_第3张图片

每次都使用webpack [--config webpack.config.js]来指定配置文件也是有些繁琐的,我们可以用npm脚本来解决这个问题

NPM 脚本(NPM Scripts)

先用npm init生成一个package.json文件,然后再修改scripts项里的内容

"scripts": {
     
  "test": "echo \"Error: no test specified\" && exit 1",
  // 添加build
  "build": "webpack"
},

这里的webpack没有指定配置文件是因为webpack打包的时候默认会运行当前目录下的webpack.config.js文件

npm run build

webpack基础配置_第4张图片

入口

在 webpack 配置中有多种方式定义 entry 属性

单个入口(简写)语法

用法:entry: string|Array
如同我们在webpack.config.js中写到的一样

module.exports = {
     
	entry: './src/index.js',
	...
}

上面单个入口文件的entry写法是下面的简写

module.exports = {
     
	entry: {
     
		main: './src/index.js'
	},
	...
}

当我们的页面需要多个模块,因此就需要把它们的依赖导向(graph)到一个“chunk”时,传入数组的方式就很有用。这里就是把index.jslist.jsdetail.js这三个模块打包到同一个bundle.js中并在页面index.html中引用

// demo2/webpack.config.js
module.exports = {
     
	entry: [
		'./src/index.js',
		'./src/list.js',
		'./src/detail.js'
	],
	output: {
     
	    path: path.resolve(__dirname, 'dist'),
	    filename: 'bundle.js'
	}
}

// demo2/src/list.js
function setElement() {
     
    var element = document.createElement('div');
    element.innerHTML = 'hello webpack demo2 list'
    return element;
}
document.getElementById('list').appendChild(setElement());

// demo2/src/detail.js
function setElement() {
     
    var element = document.createElement('div');
    element.innerHTML = 'hello webpack demo2 detail'
    return element;
}
document.getElementById('detail').appendChild(setElement());
//demo2/index.html
<body>
	
    <div id="list">div>
    <div id="detail">div>
body>
<script src="./dist/bundle.js">script>
// ...

浏览器预览效果
webpack基础配置_第5张图片

对象语法

有时候我们的项目可能会有不止一个页面,需要将多个页面分开打包,entry支持传入对象的方式。

module.exports = {
     
	// 对象形式的入口文件
	entry: {
     
		home: './src/index.js',
		list: './src/list.js',
		detail: './src/detail.js'
	},
	...
}

这时候就会分别打包三个入口js文件并且生成三个bundle文件,三个文件的名字在output中定义,所以打包结果在output中测试。

输出

在 webpack 中配置 output 属性的最低要求是,将它的值设置为一个对象,包括以下两点:

  • filename 用于输出文件的文件名。
  • 目标输出目录 path 的绝对路径。

虽然entry可以有多个入口文件,但是只能配置一个output

module.exports = {
     
	// 单个入口
	entry: './src/index.js',
	output: {
     
		path: path.resolve(__dirname, 'dist'),
		filename: 'bundle.js'
	}
};

这里根据entry单入口的情况配置的output,如果entry是多入口的情况还这样配置就会报错,Conflict: Multiple chunks emit assets to the same filename即多个文件资源有相同的文件名称,webpack提供了占位符来确保每一个输出的文件都有唯一个名称

module.exports = {
     
	// 对象形式的入口文件
	entry: {
     
		home: './src/index.js',
		list: './src/list.js',
		detail: './src/detail.js'
	},
	output: {
     
		path: path.resolve(__dirname, 'dist'),
		// filename: 'bundle.js'
		// 多文件入口时的output
		filename: '[name].bundle.js',
	}
};

这样打包出来的文件就会根据entry中键值名称来生成多个不同的文件名。

占位符

占位符 描述
[hash] 模块标识符的hash
[chunkhash] chunk内容的hash
[name] 模块名称
[id] 模块标识符
[query] 模块的query,例如:文件名?后面的字符串

Module、Chunk和Bundle的概念

  • moudle:我们写的源码,无论commonjs还是amdjs,都可以理解为一个个的module
  • chunk:当我们写的module传到webpack进行打包时,webpack会根据文件引用关系生成chunk,webpack会对这些引用文件进行一些操作。
  • bundle:webpack处理好chunk之后会输出bundle文件,这个bundle包括了最终加载和编译后的文件,所以他可以在浏览器运行。

自动生成页面
在上面的代码中我们都是手动创建html文件并引入打包后的js文件,这样不够自动化如果生成bundle引入了hash值,那么每次打包之后的js文件名也要重新替换,所以我们需要一个自动生成并引入打包后js的插件。

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

在entry入口文件为对象时我们引入了三个入口文件并在output中打包了三个bundle文件,在三个页面分别引入这三个文件

// demo3/webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
     
	// 对象形式的入口文件
	entry: {
     
		home: './src/index.js',
		list: './src/list.js',
		detail: './src/detail.js'
	},
	output: {
     
		path: path.resolve(__dirname, 'dist'),
		// filename: 'bundle.js'
		// 多文件入口时的output
		filename: '[name].bundle.js',
	},
	plugins: [
		new HtmlWebpackPlugin({
     
			template: './index.html',
			filename: 'home.html',
			chunks: ['home']
		}),
		new HtmlWebpackPlugin({
     
			template: './detail.html',
			filename: 'detail.html',
			chunks: ['detail']
		}),
		new HtmlWebpackPlugin({
     
			template: './list.html',
			filename: 'list.html',
			chunks: ['list']
		})
	]
};

以index.html为模版再创建list.html和detail.html 不用引入bundle文件,会根据配置文件在打包后自动引入。
打包后的文件目录
webpack基础配置_第6张图片

// demo3/dist/home.html
<body>
	<script src="home.bundle.js">script>
body>
// demo3/dist/list.html
<body>
    <div id="list">div>
	<script src="list.bundle.js">script>
body>
// demo3/dist/detail.html
<body>
    <div id="detail">div>
	<script src="detail.bundle.js">script>
body>

你可能感兴趣的:(webpack,webpack)