webpack打包的原理:webpack都有entry、module、loader、chunk、output等配置選項。 webpack首先會根據entry找到對應所依賴的module(webpack會把全部的文件看多模塊)進行遞歸解析,好比main.js、main.ts等等,同時也會根據loader對應的轉換規則去轉換,這些模塊會以entry爲單位進行分組,一個entry和其全部依賴的module被分到一個組,也就是一個chunk,最後webpack會把全部chunk轉換成文件輸出,在整個流程中webpack會在恰當的實際執行plugin定義的邏輯css
module.exports = function(env,argv){
return {
mode: env.production? 'production': 'development'
entry: './src/main.js',
resolve: {
},
module: {
rules: [
{
test: /\.json$/,
use: 'json-loader'
},
]
},
plugins: []
}
}
複製代碼
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/'
},
plugins: [],
resolve: {
alias: {
'@': resolve('src'),
}
},
module: {
rules: [
{
test: /\.json$/,
use: 'json-loader'
},
]
}
複製代碼
webpack將運行有配置文件導出的函數,而且等到promise返回,便於須要一部加載所需的配置變量,貌似這種方式不多見。 我見的比較可能是前兩種方式html
module.exports = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
entry: './app.js',
/* ... */
})
}, 5000)
})
}
複製代碼
Webpack 在尋找相對路徑的文件時會以context
爲根目錄,context
默認爲執行啓動 Webpack 時所在的當前工做目錄。vue
context: path.resolve(__dirname, 'app')
複製代碼
entry: string | [string]
object { <key>: string | [string] }
(function: () => string | [string] | object { <key>: string | [string] })
node
// string
entry: 'src/main.js',
// object
entry: {
main1: "src/main1.js",
main2: "src/main2.js",
}
// function ,反正這種寫法我沒見過
entry: () => new Promise((resolve) => resolve(['src/main1.js', './main2.js']))
複製代碼
path: 輸入目錄的路徑,該路徑是一個絕對路徑react
path: path.resolve(__dirname, 'dist')
複製代碼
publicPath: 若是是生產環境,將資源託管到CDN上去,這裏的地址是demojquery
publicPath: process.env.NODE_ENV === 'production' ? '/demo' : '/',
複製代碼
filename: 輸出文件的名稱,這裏的[name]
能夠看作是多個chunk的輸出webpack
filename: '[name].js',
複製代碼
chunkFilename: chunk的文件名稱git
[id].chunk.js
複製代碼
sourceMapFilename: 此選項會向硬盤寫入一個輸出文件,只在 devtool 啓用了 SourceMap 選項時才使用github
sourceMapFilename: '[file].map'
複製代碼
完整的Output的配置,最經常使用的應該是前面三項web
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: process.env.NODE_ENV === 'production' ? '/demo' : '/',
filename: '[name].js',
chunkFilename: '[id].chunk.js',
sourceMapFilename: '[file].map',
}
複製代碼
用來將Es6/Jsx轉化爲ES5,例子是JSX轉化Es5
module: {
rules:
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
}
},
複製代碼
{
test: /\.css$/,
// 排除node_modules下面的文件
exclude: /node_modules/,
// 處理的順序從後到前,即先交個css-loader,再交給style-loader
use: ['style-loader', 'css-loader']
}
複製代碼
{
test: /\.(jpg|png|gif|svg)$/,
//能夠對圖片進行大小限制
loader: "url-loader?limit=10000 } 複製代碼
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
複製代碼
該插件的做用來用來提取第三方庫和公共模塊,避免首屏加載的bundle文件或者按需加載的bundle體積過大,從而致使加載時間過長
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
module.exports = {
plugins: [
new CommonsChunkPlugin({
name: 'polyfills',
chunks: ['polyfills']
})
}
複製代碼
該插件的功能是壓縮的js代碼
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
plugins: [
new UglifyJsPlugin()
]
}
複製代碼
該插件的做用是生成html文件
const HtmlwebpackPlugin = require('html-webpack-plugin');
module.exports = {
new HtmlwebpackPlugin({
title: '',
filename: 'index.html'
}),
}
複製代碼
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
}
複製代碼
devServer: {
port: METADATA.port,
host: METADATA.host,
hot: METADATA.HMR,
public: METADATA.PUBLIC,
historyApiFallback: true,
watchOptions: {
},
setup: function(app) {
},
複製代碼
performance: {
hints:
process.env.NODE_ENV === 'production' &&
!process.env.VUE_APP_TEST &&
'warning',
},
複製代碼
// 用來加載svg格式的文件
chainWebpack: config => {
const svgRule = config.module.rule('svg')
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
},
複製代碼