在只要这几步,webpack速成不是事儿一文中, 笔者简单介绍了webpack的常见用法。能知足最基本的开发需求。在这篇文章中,再来谈谈一些较高级的应用。css
以前构建都是经过 npx webpack ...
这样的方式执行构建命令。可能你会以为这样的方式不够高效。甚至在某些特定的状况下还须要设置 Node 的环境变量。根据环境变量值的不一样,设置构建 --mode 的不一样。html
scripts 配置的入口在 package.json
中,另外再介绍下。经过执行 npm i
默认安装package.json中所有依赖。vue
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server"
},
复制代码
cross-env 设置node环境变量的插件 npm i cross-env -Dnode
npm run dev
经过图中能够看到,npm run dev
至关于 npx webpack-dev-server
react
npm run build
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server",
"build": "cross-env NODE_ENV=production webpack"
},
复制代码
先安装插件cross-env
jquery
npm i cross-env -Dwebpack
执行 npm run dev
, 先设置环境变量 NODE_ENV=devlelopment, 而后执行 webpack 命令。web
为何要设置环境变量呢? 设置环境变量后,能够在打包构建时执行相应环境变量下的脚本。npm
process.env.NODE_ENV
拿到环境变量值。作你想作的事情。哈哈哈~
_DEV_
,相似于全局变量 window//应用: 在项目 src/index.js 文件中代码里区分开发或者是生产环境
if(__DEV__){
alert('开发环境')
}else{
alert('生产环境')
}
复制代码
在webpack.config.js文件中,设置变量 let isDev = process.env.NODE_ENV === 'development',而后定义插件的disable属性的值json
plugins: [
new ExtractTextWebpackPlugin({
filename: 'css/index.css',
disable: isDev
}),
],
复制代码
.dll 为后缀的文件称为动态连接库,在一个动态连接库中能够包含给其余模块调用的函数和数据
react, react-dom 为例
let path = require('path');
let webpack = require('webpack');
module.exports = {
entry: {
vendor: ['react', 'react-dom']
},
output: {
filename: '[name].js',
path: path.join(__dirname, 'dist'),
libraryTarget: "var", //构建后输出js文件所属规范, 若是 设置为 commonjs, 则输出文件符合 commonjs规范
library: '_dll_[name]', //构建后输出js库的名字
},
mode: 'development',
plugins: [
new webpack.DllPlugin({
name: '_dll_[name]',
path: path.join(__dirname, 'dist', '[name].manifest.json')
})
],
};
复制代码
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server",
"react": "wepack --config webpack.config.react.js"
},
复制代码
在webpack.config.js中配置插件
plugins: [
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'dist', 'vendor.manifest.json')
})
]
复制代码
npm i babel-core babel-loader babel-preset-env babel-preset-react babel-preset-stage-0 -D
module: {
rules: [
{
test: /\.jsx?/,
use: 'babel-loader',
exclude:/node_modules/,
include:/src/
},
]
},
复制代码
{
"presets": [
"env",
"stage-0",
"react"
]
}
复制代码
npm run build
, 控制台打印:[./node_modules/react-dom/index.js] delegated ./node_modules/react-dom/index.js from dll-reference _dll_vendor 42 bytes {index} [built]
[./node_modules/react/index.js] delegated ./node_modules/react/index.js from dll-reference _dll_vendor 42 bytes {index} [built]
复制代码
由此能够看出项目构建时是使用的预先构建好的react库文件,从控制台打印的构建耗时也明显不一样。
index.js
import './index.css';
// if(module.hot){
// console.log('热更新');
// }
import React, { Component } from 'react'
import { render } from 'react-dom'
import a from './a.js'
render(<h1>hello zfpx</h1>, window.app)
复制代码
x.js
import React, { Component } from 'react'
import { render } from 'react-dom'
import a from './a.js'
复制代码
a.js
module.exports = {
a: 'a.js'
}
复制代码
在webpack.config.js中配置:
optimization: {
splitChunks: {
cacheGroups: {
commons: { //提供公共组件, 只要超出0字节就生产新的包
chunks: 'initial',
//miniChunks: 2,
//maxInitalRequest: 5,
name: 'commons',
minSize: 0
},
vendor: {// 抽离第三插件
test: /node_modules/,
chunks: 'initial',
name: 'vender',
priority: 10,
enforce: true
}
}
}
},
复制代码
执行构建脚本 npm run build
, 控制台打印:
若是注释相关构建信息:
在index.js中引入 jquery.js后,在a.js文件中想不引入jquery.js直接使用jquery对象
webpack.config.js中配置
module: {
rules: [
{
test: /jquery/,
use:[{
loader:'expose-loader',
options:'$'
}]
},
]
}
复制代码
或者使用webpack提供的内置插件
// 提供全局变量插件
new webpack.ProvidePlugin({
$:'jquery'
}),
复制代码
两者的区别是神马呢
1. $不会定义到window上
2. 只要是用到jquery(或者 $)的地方,当前bundle.js都会把jquery打包进去
复制代码
webpack.config.js 相关配置为:
entry: {
index: './src/index.js',
x: './src/x.js'
},
output: {
filename: '[name].[hash].bundle.js',
path: path.resolve(__dirname, 'dist'),
library: '_dll_[name]'
},
...
pugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',
hash: true
}),
]
复制代码
index.js
console.log($)
复制代码
x.js
console.log($);
复制代码
从构建的日志中能够看出,index.js构建后的文件大小和x.js构建的文件大小一致
1.导入一次,就会暴露出来
2.$会定义到在window上
复制代码
index.js
import $ from 'jquery'
console.log('index.js');
console.log($);
复制代码
x.js
console.log('x.js');
console.log($);
console.log(window.$);
复制代码
构建日志:
浏览器打印日志:
从构建的日志中能够看出,index.js构建后的文件大小和x.js构建的文件大小不一致 从浏览器打印日志能够看出,x.js在没有直接import jquery时,也能够拿到jquery对象
webpack还有不少其余适用的功能,好比在使用vue时,经常会根据路由加载相应的组件js也就是咱们所说的 按需加载。能够用到webpack代码分离中的 动态导入和懒加载(dynamic imports),优化代码加载,提高性能。