webpack4.x深入与实践

一、什么是webpack

是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求。

二、安装和命令行

1、新建一个目录,进入目录,初始化


2、安装

全局安装

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ npm install webpack -g

在输出版本时,显示,要安装webpack-cli

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack -v
The CLI moved into a separate package: webpack-cli.
Please install 'webpack-cli' in addition to webpack itself to use the CLI.
-> When using npm: npm install webpack-cli -D
-> When using yarn: yarn add webpack-cli -D
$ npm install webpack-cli -g

这样就能输出版本,可以看到我安装的是4.2.0,这里要注意,自webpack4之后,使用有很大的变化

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack -v
4.2.0

局部安装

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ cnpm install webpack webpack-cli --save-dev

(1)练习():处理js文件,在项目根目录下,新建hello.js,然后打包

$ webpack hello.js hello.bundle.js
Hash: e4a6ea308e8987e8d082
Version: webpack 4.2.0
Time: 556ms
Built at: 2018-3-27 11:35:19
 1 asset
Entrypoint main = main.js
   [0] ./hello.js 40 bytes {0} [built]
   [1] multi ./hello.js hello.bundle.js 40 bytes {0} [built]

WARNING in configuration
The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.

ERROR in multi ./hello.js hello.bundle.js
Module not found: Error: Can't resolve 'hello.bundle.js' in 'E:\workspace\xampp\htdocs\text\webpackText'
 @ multi ./hello.js hello.bundle.js

显示没有配置webpack的mode选项,默认有production和development两种,我们输入

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack --mode development
Hash: f28182541f5f8d1a0d8e
Version: webpack 4.2.0
Time: 62ms
Built at: 2018-3-27 11:42:01

ERROR in Entry module not found: Error: Can't resolve './src' in 'E:\workspace\xampp\htdocs\text\webpackText'

依然有错:未找到入口模块发成错误,

这是因为webpack4.x是以项目根目录下的./src/index.js作为入口,所以我们要新建src目录且改hello.js为index.js

这里还要注意:

webpack4.x的打包已经不能用webpack 文件a 文件b的方式,而是直接运行webpack --mode development或者webpack --mode production,这样便会默认进行打包,入口文件是'./src/index.js',输出路径是'./dist/main.js',其中src目录即index.js文件需要手动创建,而dist目录及main.js会自动生成。 

因此我们不再按webpack 文件a 文件b的方式运行webpack指令,而是直接运行

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack --mode development
Hash: 34a98f4253e13bf8f430
Version: webpack 4.2.0
Time: 108ms
Built at: 2018-3-27 11:47:52
  Asset      Size  Chunks             Chunk Names
main.js  2.85 KiB    main  [emitted]  main
Entrypoint main = main.js
[./src/index.js] 40 bytes {main} [built]

这样便能实现打包。

每次这样写是不是都点麻烦,我们可以在package.json中

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --mode development"
  },

每次执行就可以:

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ npm run dev            // == webpack --mode development

(2)练习:处理css文件

新建一个css文件style.css,在index.js中引入


然后打包:

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack --mode development
ERROR in ./src/style.css
Module parse failed: Unexpected token (1:5)
You may need an appropriate loader to handle this file type.

会报如上错误,是因为webpack不支持css文件类型,需要依赖loader

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ npm install css-loader style-loader --save-dev

css-loader:使webpack可以处理css文件

style-loader:新建一个style标签,把css-loader处理过的文件放进去,然后插入到HTML标签中

安装之后使用(直接在文件前):

或者(在命令行):

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack --mode development --module-bind 'css=style-loader!css-loader'         // 给css绑定。。。。

那每次更新都要执行一次,有没有自动更新的???

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack --mode development --module-bind 'css=style-loader!css-loader' --watch      // watch参数监听,每次保存文件会自动执行

(3)其他参数:

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/webpackText
$ webpack --mode development --module-bind 'css=style-loader!css-loader' --progress --display-modules --display-reasons

--progerss:会出现打包过程,有百分比进度条

--display-modules:会把所有打包的模块列出来

--display-reasons:会把打包的原因列出来

三、webpack的配置

(1)新建一个项目并初始化

lenovo@DESKTOP-NL309GS MINGW64 /
$  cd e:/workspace/xampp/htdocs/text/demo/webpack-demo
$ npm init
$ cnpm install webpack webpack-cli --save-dev

(2)新建一个文件webpack.config.js(默认名),是在使用webpack时默认的配置文件

单文件输入:

const path = require('path');

module.exports = {
	entry: './src/js/main.js',                                // 入口文件
	output: {                                                 // 出口文件
		path: path.resolve(__dirname, 'dist/js'),         // 出口文件位置,一定要是绝对路径
		filename: 'bundle.js'                             // 出口文件名
	}
}

上面:将会打包。。。main.js文件到。。。bundle.js文件

多文件输入:

const path = require('path');

module.exports = {
	entry: {
		main: './src/js/main.js',   // 入口文件
		a: './src/js/a.js'
	},
	output: {            // 出口文件          
		path: path.resolve(__dirname, 'dist/js'),         // 出口文件位置
		filename: '[name].js'      // 出口文件名,name就是entry的键名
	}
}

四、自动生成HTML页面文件

(1)安装html-webpack-plugin插件

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install html-webpack-plugin --save-dev

(2)在webpack配置package.config.js中

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

module.exports = {
	entry: {
		main: './src/js/main.js',   // 入口文件
		a: './src/js/a.js'
	},
	output: {            // 出口文件          
		path: path.resolve(__dirname, 'dist'),         // 出口文件位置
		filename: 'js/[name].js'      // 出口文件名
	},
	plugins: [
		new htmlWebpackPlugin({
			filename: '[name]-[hash].html',         // 生成的HTML名,路径为上面output中的path
			template: './index.html',               // 会与根目录下的index.html相关联,把根目录下index的东西都放到生成的HTML中
			inject: 'head'                          // 打包后的script放到head中
		})
	]
}

(3)传参使用

1、参数

plugins: [
		new htmlWebpackPlugin({
			filename: 'index.html',
			template: './index.html',
			title: 'hello world'
		})
	]
在根目录下的index.html中
<h2><%= htmlWebpackPlugin.options.title %></h2>

生成的dist/index.html中

<h2>hello world</h2>

2、上线地址

output: {            // 出口文件          
		path: path.resolve(__dirname, 'dist'),         // 出口文件位置
		filename: 'js/[name].js',      // 出口文件名,
		publicPath: 'http://cdn.com/'    // 上线的地址
	},

在生成的index.html中

<script type="text/javascript" src="http://cdn.com/js/main.js"></script>
<script type="text/javascript" src="http://cdn.com/js/a.js"></script>

3、html压缩

title: 'hello world',
minify: {
    removeComments: true,        // 去掉注释
    collapseWhitespace: true     // 去掉空格
}

4、多页面应用,生成多个html文件

new htmlWebpackPlugin({
	filename: 'main.html',
	template: './index.html',
	title: 'hello world',
	chunks: ['main', 'a']     // 会引入main.js和a.js
}),
new htmlWebpackPlugin({
	filename: 'a.html',
	template: './index.html',
	title: 'hello world',
	excludeChunks: ['main']    // 会引入除main以外的js
})

五、loader的配置

1、解析es6语法

(1)安装babel

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install babel-loader babel-core babel-preset-env --save-dev

(2)配置webpack

module: {
    rules: [
	{
		test: /\.js$/,               // 匹配js文件
		loader: 'babel-loader',
		exclude: path.resolve(__dirname, 'node_modules'),    // 匹配时忽略这个目录,提高打包速度
		include: path.resolve(__dirname, 'src'),             // 匹配时查找的范围
		query: {
			presets: ['env']
			}
]
},

2、解析css

(1)安装style-loader和css-loader

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install style-loader css-loader --save-dev

(2)配置webpack

{
	test: /\.css$/,
	loader: 'style-loader!css-loader'           // 从右到左执行,所以注意顺序
}

(3)在项目中经常有类似-webkit的前缀,每次写很麻烦,这里就要用到postcss-loader,后处理loader

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install postcss-loader autoprefixer --save-dev                                      // autoprefixer是自动补全

配置webpack

{
	test: /\.css$/,
	use: [
		'style-loader',                                                // 注意顺序
		{ loader: 'css-loader', options: { importLoaders: 1 } },       // 在css中使用@import引入其他文件时,
		'postcss-loader'                                               // 不加importLoaders,postcss-loader不会操作引入的文件
	]
}

新建一个postcss.config.js文件和webpack.config.js同级

module.exports = {
	plugins: [
		require('autoprefixer')
	]
}

此时,如果你打包,并不会报错,但是前缀可能也没有,所以需要在package.json中加入

"browserslist": [
    "> 1%",                                // 全球浏览器使用率大于1%,最新两个版本并且是IE8以上的浏览器,加前缀
    "last 2 versions",
    "not ie <= 8"
  ]

3、解析less

(1)安装

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install less less-loader --save-dev

(2)webpack的配置

{
	test: /\.less$/,
	loader: 'style-loader!css-loader!postcss-loader!less-loader'     // 不用加importLoader,less-loader默认会有
}
4、解析sass

sass的使用和less一样,只要把less改为sass就行了

5、处理html模板文件

(1)安装html-loader

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install html-loader --save-dev

(2)配置

{
	test: /\.html$/,
	loader: 'html-loader'
}

(3)使用

layer.js

import tpl from './layer.html';
import './layer.less';

function layer () {
	return {
		name: 'layer',
		tpl: tpl
	}
}

export default layer;

app.js

import Layer from './components/layer/layer.js';
import './css/common.css';

const App = function () {
	var app = document.getElementById('app');
	var layer = new Layer();
	app.innerHTML = layer.tpl;
}

App();

6、使用ejs模板文件,后缀为tpl或ejs

(1)安装

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install ejs-loader --save-dev

(2)配置

{
	test: /\.tpl$/,
	loader: 'ejs-loader'
}

(3)使用

layer.tpl

<div class="layer">
	<div>this is <%= name %></div>
	<% for (var i=0; i<arr.length; i++) { %> 
		<%= arr[i] %>
	<% } %>
</div>

layer.js

import './layer.less';
import tpl from './layer.tpl';            // 返回是一个函数

function layer () {
	return {
		name: 'layer',
		tpl: tpl
	}
}

export default layer;

app.js

import Layer from './components/layer/layer.js';
import './css/common.css';

const App = function () {
	var app = document.getElementById('app');
	var layer = new Layer();
	app.innerHTML = layer.tpl({
		name: 'xueer',
		arr: ['apple', 'oppo', 'xiaomi']
	});
}

App();

7、用file-loader处理图片

(1)安装

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install file-loader --save-dev

(2)配置

{
	test: /\.(png|jpg|gif|svg)$/i,
	loader: 'file-loader'
}

(3)使用

layer.less

.layer {
	width: 600px;
	height: 200px;
	background: url('../../assets/1.png');
	div {
		width: 400px;
		height: 100px;
		background: red;
	}
	.flex {
		display: flex;
	}
}

若是在.tpl或.ejs中使用

<img src="${ require('../../assets/1.png') }">

(4)也可以加参数

{
	test: /\.(png|jpg|gif|svg)$/i,
	loader: 'file-loader',
	query: {
		name: 'assets/[name]-[hash:5].[ext]'
	}
}

8、使用url-loader处理图片(会影响文件大小)

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install url-loader --save-dev
{
	test: /\.(png|jpg|gif|svg)$/i,
	loader: 'url-loader',
	query: {
		limit: 30000,                     // 当图片小于30kb的时候,图片变为base64位,不打包
		name: 'assets/[name]-[hash:5].[ext]'
	}
}

9、通过image-webpack-loader和url-loader结合:先有image-webpack-loader打包,在通过url-loader

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/text/demo/webpack-demo
$ cnpm install image-webpack-loader --save-dev
{
	test: /\.(png|jpg|gif|svg)$/i,
	loaders: [
		'url-loader?limit=1000&name=assets/[name]-[hash:5].[ext]',
		'image-webpack-loader'
	]
}










猜你喜欢

转载自blog.csdn.net/snow_small/article/details/79709585