一篇文搞懂webpack[零基础教学+手把手带你搞项目]

Posted 前端呆头鹅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇文搞懂webpack[零基础教学+手把手带你搞项目]相关的知识,希望对你有一定的参考价值。

一 简介

webpack现在可谓炙手可热,要是不懂,就难免让人觉得有点跟不上时代。

其实webpack只是一种工具,我们以使用为目的去学习它,就一点也不难哦,本篇文章让您在一个小时内上手webpack,没时间学习也可以先收藏哦。

webpack主要用于兼容性处理,代码预处理转换处理,压缩处理。

如转换ES6语法,转换JSX 指令等

CSS前缀补全/预处理器,代码压缩混淆,图片压缩等。

webpack的配置文件默认为webpack.config.js。

webpack --config命令可用于指定配置文件。

二 新手上路

2.1 环境准备

安装nodejs和npm,直接在nodejs官网下载安装包即可,npm作为nodejs附属包同时自动安装,无需另外安装。

使用nodejs安装包安装后可用命令行在cmd窗口查看安装版本。
在这里插入图片描述

2.2 创建项目

首先,创建项目目录(空目录),使用命令行创建一个初始化的package.json

npm init -y
在这里插入图片描述

向项目目录中安装webpack依赖,安装后目录中出现node_modules文件。
npm install webpack webpack-cli --save-dev
在这里插入图片描述
注意到上文命令行中包含后缀 --save-dev,含义如下。

  • –save : dependencies 键下,发布后还需要依赖的模块,譬如像jQuery库或者Angular框架类似的,我们在开发完后后肯定还要依赖它们,否则就运行不了。
  • –save-dev : devDependencies 键下,开发时的依赖比如安装 js的压缩包gulp-uglify 因为我们在发布后用不到它,而只是在我们开发才用到它。

主要区别在于打包后是否保留该依赖,webpack本身是打包工具,当然不需要保留啦。

安装成功后查看安装情况

./node_modules/.bin/webpack -v

在这里插入图片描述

2.3 项目上手

现在我们就可以使用webpack做项目了,首先做一个最简单的例子。

首先z在项目目录中创建配置文件webpack.config.js,

'use strict'

const path = require('path'); // 引入一个依赖

module.exports = {
    entry: './src/index.js', // 入口
    output: { // 出口
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    mode: 'production'
};

在上面文件中,我们指定入口为’./src/index.js’,输出文件在dist文件夹中,名字为’bundle.js’。

翻译一下也就是,webpack会以’./src/index.js’为入口,将其与其所有的依赖打包为一个出口文件’bundle.js’放置在目录dist中。

我们首先创建文件’./src/index.js’与其依赖文件’./src/helloworld.js’。

在index.js中引入helloworld.js文件。

// './src/index.js'
import { helloworld } from './helloworld';

document.write(helloworld());
// './src/helloworld.js'
export function helloworld() {
    return 'hello webpack'
}

此时项目结构如下图。

在这里插入图片描述
文件准备完毕,我们使用webpack命令行打包。

./node_modules/.bin/webpack

在这里插入图片描述

项目目录下,出现了文件夹dist,其中含有bundle.js,与前面配置文件出口路径与名称对应。

在这里插入图片描述

可以看到,bundle.js文件是入口文件的整合版,运行效果与入口文件是相同的,只是少了依赖而已。

刚刚使用./node_modules/.bin/webpack打包,未免繁琐,这里可以通过在package.json中对scripts添加配置的方式,设置快捷命令。

{
  "name": "webpackTest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1",
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.38.1",
    "webpack-cli": "^4.7.0"
  }
}
rm -rf dist // 删除之前的打包文件
npm run build // 打包文件 生成与刚刚相同的文件

三 webpack基础用法

3.1 核心概念了解

入口 - entry

刚刚的配置文件中见过,用于指定打包文件入口。

单入口情况下为字符串,多入口情况下为key-value对象。

刚刚的示例为单入口文件。

出口 - Output

刚刚的配置文件中见过,用于指定编译后的文件输出。

// 单入口 单出口
module.exports = {
    entry: './src/index.js', // 入口
    output: { // 出口
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
    }
};
// 多入口 多出口
module.exports = {
    entry: {
    	app: './src/app.js',
    	search: './src/search.js'
    }
    output: { // 出口
        path: path.join(__dirname, 'dist'),
        filename: '[name].js'
    }
};

可以看到,对于多入口出口配置,output中内容没有太大改变,其实是使用占位符[name]来实现文件动态命名的,打包后的dist目录中,有着对应入口文件的n个出口文件,名称与entry中的key值一致。

上面的配置文件中,打包结果为dist中出现两个文件,分别为app.js和search.js。

加载 - loaders

webpack原生支持js和json,通过loaders做其他文件类型的转换,如vue等,将其他文件类型转化为有效的模块,添加到依赖图中。

本身是一个函数,接受源文件作为参数,返回转换的结果。

常见loaders:

babel-loader转换ES6.ES7等
css-loader支持.css文件的加载和解析
less-loader将less文件转换为css
ts-loader将TS转换成JS
file-loader进行图片 字体等的打包
raw-loader将文件以字符串的形式导入
thread-loader多进程打包JS和CSS

用法

module.exports = {
	module: {
		rules: [
			{test:/\\.txt$/,use:'raw-loader'} // 匹配规则 loader名称
		]
	}
}

插件 - Plugins

插件,增强功能。作用于整个构建过程。

常用插件

用法

module.exports = {
	plugins: [
		new htmlWebpackPlugin({template: './src/index.html'})
		// 创建html文件去承载输出的bundle
	]
}

环境 - Mode

指定当前的构建环境是:production development none

默认为 production。

通过对mode的不同设置,可以使用webpack不同内置函数。

3.2 基础解析-loaders使用

ES6 与 JSX

使用babel-loader完成。

npm i @babel/core @babel/preset-env babel-loader -D

在src同级目录下创建babel配置文件.babelrc,书写配置。

{
	"presets": [
		"@babel/preset-env"
	]
}

修改webpack配置文件。

rules: [
	{
		test:/.js$/,
		use: 'babel-loader'
	}
]

配置完成后查看效果。

rm -rf dist
npm run build

此时已经解析成功了。

那如果是React语法如何解析呢。

安装babel-react。

npm i react react-dom @babel/preset-react -D

修改babel配置文件.babelrc。

{
	"presets": [
		"@babel/preset-env",
		"@babel/preset-react"
	]
}

书写一个简单的react-js文件,文件的含义是将一个模板放置到一个DOM节点上。

npm run build 构建即可查看效果。

将输出的JS文件放置到一个新建的html文件中,文件中含有对应的节点,就可以成功插入了。

CSS解析

解析CSS使用css-loader,将css转换为commonjs对象,使用style-loader,将样式通过

首先在项目中安装两个依赖。

npm i style-loader css-loader -D

在项目中创建css文件,写入一些样式,并在刚刚的react的js文件中引入使用。

在webpack配置文件中rules中添加loader。

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

再编译,生成的js文件,放置在html中就有对应效果了。

但是这时候还是没有单独的css文件的,要将css文件分离出来,要使用插件extract-text-webpack-plugin。

也可以使用mini-css-extract-plugin,都是用来抽离css样式,防止将样式打包在js中引起页面样式加载错乱的现象

extract-text-webpack-plugin 4.0的beta版本才支持webpack4.x 或者使用mini-css-extract-plugin
extract-text-webpack-plugin 默认版本 在webpack3.x可用

npm install extract-text-webpack-plugin --save-dev
var Ex = require('extract-text-webpack-plugin');
// ...省略
module: {
  loaders: [{
    test: /\\.css/,
    loader: Ex.extract('style-loader', 'css-loader','less-loader')  // 单独打包出CSS,这里配置注意下
  }]
},
plugins: [
  new Ex("[name].css")
]

如果我们想要一个加载器数组,我们必须使用use,如果它只是一个加载器,那么我们必须使用loader。

Less解析

安装less和less-loader依赖。

npm i less less-loader -D

将刚刚的css文件转换为less文件,之后在webpack中配置rules。

	{
		test: /.less$/,
		use: [
			'style-loader',
			'css-loader',
            'less-loader'
		]
	}

然后打包查看效果即可。

解析图片

使用file-loader处理文件。

在src目录下放置图片logo.png,并在项目中引入使用。

npm i file-loader -D

在webpack配置文件中配置使用。

{
	test: /.(png|jpg|gif|jpeg)$/,
	use: 'file-loader'
}

打包即可。

解析字体

与图片相同使用file-loader。

刚刚已经安装过依赖了,无需再安装,我们直接在css中引入和使用字体即可。

在webpack配置文件中添加配置。

{
	test: /.(woff|woff2|eit|ttf|otf)$/,
	use: 'file-loader'
}

然后打包编译即可。

四 webpack文件监听

文件监听是指在发现源码发生变化时,自动构建新的输出文件。

webpack开启监听模式,有两种方式。

  • 启动webpack命令时添加–watch参数。
  • webpack配置文件中添加watch:true。

首先我们使用第一种方式。

在package.json的scripts中添加配置watch。

  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1",
    "build": "webpack",
    "watch": "webpack --watch"
  },

然后运行构建的时候,使用 npm run watch构建。

webpack会轮询判断文件的最后编辑时间是否变化,变化后会等待一段时间后执行。

刚刚说了第二种方式,也可在配置文件中配置。

webpack相关配置。

module.export = {
	// 默认false 也就是不开启
	watch: true,
	// 只有开启监听模式时下面的设置才有效
	watchOptions: {
		// 忽略的文件 默认为空
		ignored:/node_modules/,
		// 监听后等待时候 默认300
		aggregateTimeout:300,
		// 轮询时间 默认1000
		poll:1000
	}
}

如此,当我在编辑了文件的时候,保存后webpack就会自动编译。

五 功能优化-plugins使用

5.1 webpack热更新

刚刚添加了自动构建功能,但是构建完成后需要我们手动刷新浏览器,浏览器的自动刷新在webpack中也有体现,就叫做热更新。

也就是webpack-dev-server。

安装该包依赖。

npm i webpack-dev-server -D

我们在在package.json的scripts中添加配置dev。

  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1",
    "build": "webpack",
    "watch": "webpack --watch",
    "dev": "webpack-dev-server --open"
  },

在webpack配置中引入并注册热更新插件,并进行配置。

// webpack.config.js
const webpack = require('webpack');
// webpack.config.js
plugins: [
	new webpack.HotModuleReplacementPlugin()
],
devServer: {
	contentBase: './dist',
	hot:true
}

热更新的内容不会保存到磁盘,而是放置在内存中。

这时可能会有一个报错:

Cannot find module 'webpack-cli/bin/config-yargs'

是因为webpack-cli的新版本对webpack-dev-server版本的不兼容,之后降低webpack-cli的版本为 "^3.3.12"

npm i webpack-cli@3.3.12 -D 就ok了。

5.2 代码压缩

JS压缩

webpack已经内置了uglifyjs-webpack-plugin插件进行JS压缩。

CSS压缩

使用插件optimize-css-assets-webpack-plugin,同时使用cssnano。

安装依赖。

npm i optimize-css-assets-webpack-plugin
npm i cssnano -D

引用插件。

plugins: [
	...,
	new OptimizeCSSAssetsPlugin({
		assetNameRegExp: /.css$/g,
		cssProcessor: require('cssnano')
	})
]

然后打包,打包成的就是压缩的css了。

html压缩

设置插件html-webpack-plugin,设置压缩参数。

在html中新建html模板。

在webpack配置文件中引入html-webpack-plugin。

import HtmlWebpackPlugin = require(html-webpack-plugin)

在配置文件中配置插件。

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  ...
  plugins: [new HtmlWebpackPlugin()],
};

上面是最简单用法,这将会生成一个包含以下内容的 dist/index.html 文件。

如果你有多个 webpack 入口,他们都会在已生成 HTML 文件中的 <script> 标签内引入。

如果在 webpack 的输出中有任何 CSS 资源(例如,使用 MiniCssExtractPlugin 提取的 CSS),那么这些资源也会在 HTML 文件 <head> 元素中的 <link> 标签内引入。

也可以为这个插件传入一写参数,来指定入口html等值。

以上是关于一篇文搞懂webpack[零基础教学+手把手带你搞项目]的主要内容,如果未能解决你的问题,请参考以下文章

一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)

一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)

一篇带你搞懂 java 集合

一篇带你搞懂 java 集合

一篇文章带你搞懂spring全家桶套餐

干货|手把手带你搞懂Modbus通信协议