resolve:{
extensions:['.js','.css','.vue']
},
复制代码
resolve:{
extensions:['.js','.css','.vue'],
alias:{
bootstrap:'bootstrap/dist/css/bootstrap.css' //import 'bootstrap'会找对应的路径
}
},
复制代码
resolve:{
extensions:['.js','.css','.vue'],
mainFields:['style','main'] //先找style字段再找main
},
复制代码
resolve:{
extensions:['.js','.css','.vue'],
mainFields:['style','main'],
modules:[path.resolve(__dirname,node_modules),modle] //modle为本身写的插件或组件
},
复制代码
resolve:{
extensions:['.js','.css','.vue'],
mainFields:['style','main'],
modules:[path.resolve(__dirname,node_modules),modle],
mianFiles:['index.js','main.js']
},
复制代码
对于某些库,例如:lodash和jquery,其中没有使用require和import引用模块,那么库就不须要使用webpack进行解析分析依赖。javascript
module.exports = {
entry:{
index:'./src/index'
},
output: {
filename:'[name].[hash:8].js',
path: path.resolve(__dirname,'dist')
},
module: {
noParse:/jquery|lodash/,
rules:[]
}
}
复制代码
npm install jquery
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry:{
index:'./src/index'
},
output: {
filename:'[name].[hash:8].js',
path: path.resolve(__dirname,'dist')
},
module: {
rules:[
{
test:/\.css$/,
use:[{
loader:MiniCssExtractPlugin.loader,
},'css-loader']
},
{
test:/\.jpg|png/,
use:{
loader:'url-loader',
options:{
limit:8*1024
}
}
},
{
test:/\.html$/,
use:'html-withimg-loader'
},
{ //使用babel-loader
test:/\.js$/,
use:'babel-loader',
exclude:'/node_modules/'
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.ProvidePlugin({
"$":'jquery' //在全局下添加$变量,不须要再次引入
}),
new MiniCssExtractPlugin({
filename:index.css,
}),
new HtmlWebpackPlugin({
template:'./src/index.html',
filename:'index.html',
chunks:['index']
})
],
devServer: {
contentBase:'./dist',
port:'3000',
hot:true
},
resolve:{},
}
复制代码
//index.js
console.log($) //在全局下添加$变量,不须要再次引入import
//undefine,不会挂载在window上,页面中插入的script标签中获取不到
console.log(window.$)
复制代码
npm install export-loader -D
复制代码
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry:{
index:'./src/index'
},
output: {
filename:'[name].[hash:8].js',
path: path.resolve(__dirname,'dist')
},
module: {
rules:[
{
test:/\.css$/,
use:[{
loader:MiniCssExtractPlugin.loader,
},'css-loader']
},
{
test:/\.jpg|png/,
use:{
loader:'url-loader',
options:{
limit:8*1024
}
}
},
{
test:/\.html$/,
use:'html-withimg-loader'
},
{
test:/\.js$/,
use:'babel-loader',
exclude:'/node_modules/'
},
{
test:/jquery/,
use:{
loader:'expose-loader', //expose-loader暴露$
options:{
$:'jquery'
}
},
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({
filename:index.css,
}),
new HtmlWebpackPlugin({
template:'./src/index.html',
filename:'index.html',
chunks:['index']
})
],
devServer: {
contentBase:'./dist',
port:'3000',
hot:true
},
resolve:{},
}
复制代码
//index.js
const $ = require('jquery');
console.log($)
console.log(window.$) //可以挂载在window上
复制代码
webpack支持多个线程进行同时进行打包,以便提升编译打包的速度,可是须要注意,若是项目比较简单,不要采用这种方式,由于线程时须要cpu的花销的,简单的项目而使用多线程编译打包,不只不能加快打包的速度,反而会下降打包的速度css
const path = require('path');
cosnt HappyPack = require('happypack');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname,'dist'),
filename: 'index_bundle.js',
},
module:{
rules:[
{
test: /\.js$/,
loader: 'happypack/loader?id=js',
exclude: /node_modules/,
include: path.resolve(__dirname,'src')
},
{
test: /\.css$/,
loader: 'happypack/loader?id=css',
exclude: /node_modules/,
include: path.resolve(__dirname,'src')
}]
},
plugins: [
new HappyPack({
id: 'js',
threadPool: happyThreadPool,
loaders: [ 'babel-loader' ]
}),
new HappyPack({
id: 'css',
threadPool: happyThreadPool,
loaders: [ 'style-loader', 'css-loader', 'less-loader' ]
})
]
}
复制代码
预先编译和打包不会存在变更的文件,在业务代码中直接引入,加快webpack编译打包的速度,可是并不能减小最后生成的代码体积。html
import React,{Component} from 'react';
import ReactDoM,{render} from 'react-dom';
复制代码
这样会存在一个问题,react和reat-dom中的代码基本不会修改,因此用户编写代码修改时,这些代码也会从新编译和打包,这样就很浪费时间,Dllplugin一次编译打包后就会生成一份不变的代码供其余模块引用,节省开发时编译打包的时间。vue
const path = require('path');
const webpack = require('webpack');
module.exports ={
entry: {
vendor: ['react', 'redux', 'react-router'],
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].dll.js',
library: '[name]_[hash]' //提供全局的变量
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, 'dist', '[name].manifest.json'),
name: '[name]_[hash]',
}),
],
};
复制代码
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack",
"dll":"webpack --config webpack.dll.config.js"
},
复制代码
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname,'dist'),
filename: 'index_bundle.js',
},
plugins: [
new webpack.DllReferencePlugin({
context: path.join(__dirname),
manifest:path.resolve(__dirname,'dist','vendor.manifest.json')
}),
new HtmlWebpackPlugin(),
new AddAssetHtmlPlugin({
filepath: path.resolve(__dirname,'dist','vendor.manifest.json')
}),
],
};
复制代码
结构会生成这样的页面java
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<script type="text/javascript" src="vendor-manifest.json"></script>
<script type="text/javascript" src="index_bundle.js"></script>
</body>
</html>
复制代码
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
//两个模块都引用了c模块和d模块
pageA:'./src/pageA',
pageB:'./src/pageB',
},
output: {
path: path.resolve(__dirname,'dist'),
filename: '[name].js',
},
optimization:{
splitChunks:{
cacheGroups:{
common:{
chunks:'initial',
minChunks:2, //用两个模块以上同时引用的模块才会抽离出来
minSize:0 //限制大小,过小了不必抽离
}
}
}
},
plugins:[
new HtmlWebpackPlugin()
]
}
复制代码
//pageA.js pageB.js
import './pageC'
import './pageD'
复制代码
//pageC.js
console.log('c')
复制代码
console.log('d')
复制代码
生成的页面node
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<script type="text/javascript" src="common~pageA~pageB.js"></script>
<script type="text/javascript" src="pageA.js"></script>
<script type="text/javascript" src="pageB.js"></script>
</body>
</html>
复制代码
将一些公共的文件例如react、react-dom等文件以cdn的方式引入,而后源文件中就不须要打包这些模块,增长一次请求可是减小代码体积。react
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry:{
index:'./src/index'
},
output: {
filename:'[name].[hash:8].js',
path: path.resolve(__dirname,'dist')
},
module: {
rules:[
{
test:/\.css$/,
use:[{
loader:MiniCssExtractPlugin.loader,
},'css-loader']
},
{
test:/\.jpg|png/,
use:{
loader:'url-loader',
options:{
limit:8*1024
}
}
},
{
test:/\.html$/,
use:'html-withimg-loader'
},
{
test:/\.js$/,
use:'babel-loader',
exclude:'/node_modules/'
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({
filename:index.css,
}),
new HtmlWebpackPlugin({
template:'./src/index.html',
filename:'index.html',
chunks:['index']
})
],
externals:{
'jquery':'$' //代表jquery是外链CDN引用
}
devServer: {
contentBase:'./dist',
port:'3000',
hot:true
},
resolve:{},
}
复制代码
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
</body>
</html>
复制代码
IgnorePlugin用于忽略某些特定的模块,让 webpack 不把这些指定的模块打包进去jquery
const path = require('path');
const webpack =require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry:{
index:'./src/index'
},
output: {
filename:'[name].[hash:8].js',
path: path.resolve(__dirname,'dist')
},
module: {},
plugins: [
//moment中的语言包很大,其余语言根本就没有必要打包
//须要的语言单独引入
new webpack.IgnorePlugin(/^\.\/locale/,/moment$/)
],
devServer: {
contentBase:'./dist',
port:'3000',
hot:true
},
resolve:{},
}
复制代码
import moment from 'moment';
//须要的语言单独引入
require('moment/locale/zh-cn');
console.log(moment);
复制代码
使用IgnorePlugin前 webpack
webpack内部定义用户异步加载模块的使用方法,用于减小资源文件的体积。es6
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {HashRouter as Router,Route} from 'react-router-dom';
import Bundle from './Bundle';
let LazyAbout=(props) => (<Bundle {...props} load={()=>import('./About')}/>)
let Home=() => <div>Home</div>
ReactDOM.render(
<Router>
<div>
<Route path="/" component={Home} />
<Route path="/about" component={LazyAbout}/>
</div>
</Router>,document.getElementById('root'));
复制代码
//Bundle
import React from 'react';
export default class Bundle extends React.Component{
state={Mod: null}
componentWillMount() {
this.props.load().then(mod=>this.setState({Mod: mod.default? mod.default:mod}));
}
render() {
let Mod=this.state.Mod;
return Mod&&<Mod {...this.props}/>;
}
}
复制代码
//About
import React from 'react';
export default props => <div>About</div>
复制代码
tree-shaking会将一些没有用到的代码自动删除掉,这是webpack4内部自带的功能,这里有一个前提就是代码必须采用es6的模块方式import,否则没有办法使用tree-shaking
//a.js
export a = ()=>'a';
export b = ()=>'b';
复制代码
//index.js
import {a} from './a'
console.log(a());
复制代码
最后打后的代码会删除掉b
webpack会将某些代码进行优化,以更简洁的方式来替代。
//c.js
export default 'kbz'
复制代码
//index.js
import c from './c'
console.log(c);
//这两行会简化为 var c = 'kbz'
复制代码
const path = require('path');
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname,'dist'),
filename: 'index_bundle.js',
},
module:{
},
plugins: [
new ModuleConcatenationPlugin()
]
}
复制代码
以上就是一些关于webpack优化的一些手段。