/** 若是您發現錯誤,請必定要告訴窩,拯救一個辣雞(但很帥)的少年就靠您了!*/ css
本文基於 webpack4html
webpack 是一個打包工具。vue
本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundle。node
loader 用於對模塊的源代碼進行轉換。loader 可使你在 import 或"加載"模塊時預處理文件。經過 loader 能夠把其餘格式的文件轉爲 webpack 能夠打包的模塊。react
loader 有三種配置方式webpack
module.rules
字段配置。import
等引入語句中指定 loader。使用 !
將資源中的 loader 分開。分開的每一個部分都相對於當前目錄解析。一組鏈式的 loader 將按照相反的順序執行。git
經常使用 loader :babel-loader、style-loader、css-loader、less-loader、postcss-loader、eslint-loader、vue-loader ……github
插件目的在於解決 loader 沒法實現的其餘事。web
經常使用 plugins:DefinePlugin(定義全局常量)、copy-webpack-plugin(複製文件)、extract-text-webpack-plugin(分離出CSS文件)IgnorePlugin(忽略文件)……json
絕對路徑
相對路徑
在 import/require
中給定的相對路徑,會添加此上下文路徑(context path),以產生模塊的絕對路徑(absolute path)。
模塊路徑
模塊將在 resolve.modules
中指定的全部目錄(默認是 [node_modules]
)內搜索。
若是路徑指向一個文件
[resolve.extensions]
選項做爲文件擴展名來解析,此選項告訴解析器在解析中可以接受哪些擴展名(例如 .js
, .jsx
)。若是路徑指向一個文件夾件
package.json
文件,則按照順序查找 resolve.mainFields
配置選項中指定的字段。而且 package.json
中的第一個這樣的字段肯定文件路徑。package.json
文件不存在或者 package.json
文件中的 main
字段沒有返回一個有效路徑,則按照順序查找 resolve.mainFiles
配置選項中指定的文件名,看是否能在 import/require
目錄下匹配到一個存在的文件名。resolve.extensions
選項採用相似的方法進行解析。hash
:項目中任何一個文件改動後就會被從新建立,全部的文件名都會使用相同的 hash 指紋。chunkhash
:是根據具體模塊文件的內容計算所得的 hash 值,因此某個文件的改動只會影響它自己的 hash 指紋,不會影響其餘文件。contenthash
:表明的是文本文件內容的 hash 值,是指打包後文件的內容。啓動 webpack-dev-server
至關於先經過 webpack 打包,而後,啓動本地靜態服務器運行打包後的代碼。經過設置 mode
爲 development
可使用一些 webpack 爲 development
模式預設的一些配置。
能夠經過 devServer
字段來配置 webpack-dev-server 。
模塊熱替換功能會在應用程序運行過程當中,替換、添加或刪除模塊,而無需從新加載整個頁面。主要是經過如下幾種方式,來顯著加快開發速度:
經過設置 devServer.hot=true
能夠在 webpack-dev-server 中使用 HMR 。
一個簡單的 react 項目配置。使用了經常使用插件和 loader ,完整配置可見 github.com/G-lory/fron…
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
// mode: 'production'
/** * 配置入口文件 * 至關於 * entry { main: './src/index.js' } * 能夠配置多個入口 */
entry: './src/index.js',
/** * 配置輸出路徑和文件名 */
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[chunkhash].js'
},
module: {
rules: [
/** * 配置 babel-loader 來使用 ES6 和 react 語法 * test 和 include/exclude 指定做用的文件 * use 指定 loader 和相關配置 */
{
test: /\.js$/,
include: [
path.resolve(__dirname, 'src') // 指定哪些路徑下的文件須要通過 babel-loader 處理
],
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
},
/** * 將 eslint-loader 設置爲前置 loader * 由於 eslint 檢查的是未經處理的源代碼 * 要保證最早進行處理 * 經過 npx eslint --init 命令初始化一個 eslint 配置文件 */
{
enforce: "pre",
test: /\.js$/,
include: [
path.resolve(__dirname, 'src')
],
loader: "eslint-loader"
},
/** * v4 之後使用 mini-css-extract-plugin 代替 extract-text-webpack-plugin * style-loader 是把樣式經過 js 生成樣式插入到 html * MiniCssExtractPlugin 是提取樣式到文件 * 因此使用 MiniCssExtractPlugin 就不須要 style-loader 了 * css-loader 處理 css 文件的引用 @import and url() like import/require() * postcss-loader 配置見文件 postcss.config.js 自動添加瀏覽器前綴 */
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader"
]
},
/** * 處理圖片 */
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]'
}
},
],
}
]
},
plugins: [
/** * 將打包好的js和css文件在指定html文件中自動引入 */
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'public/index.html'
}),
/** * 提取css到指定文件 */
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
// chunkFilename: "[id].css"
}),
/** * 打包前刪除以前的生成文件 * 默認刪除 <PROJECT_DIR>/dist/ 下的全部文件 */
new CleanWebpackPlugin(),
/** * 用於建立一些在編譯時能夠配置的全局常量 */
new webpack.DefinePlugin({
VERSION: JSON.stringify('5fa3b9')
// 若是指定了 mode 會自動添加變量 process.env.NODE_ENV = mode
// "process.env.NODE_ENV": JSON.stringify("production")
}),
/** * 複製文件 不通過webpack處理 直接複製到指定目錄 * from 配置來源,to 配置目標路徑 */
new CopyWebpackPlugin([
{ from: 'src/assets/favicon.ico', to: 'favicon.ico' }
])
],
/** * 配置代碼的解析路徑 */
resolve: {
/** * 配置路徑別名 */
alias: {
'@src': path.resolve(__dirname, 'src')
},
/** * 搜索模塊路徑的目錄 */
modules: [
"node_modules"
],
// 查找路徑是自動添加的文件後綴
// 減小配置以防下降查找效率
extensions: [".js", ".jsx"]
},
optimization: {
// mode 爲 production 時
// 默認開啓壓縮
// minimize: true
// 能夠經過提供一個或多個定製過的 TerserPlugin 實例,覆蓋默認壓縮工具(minimizer)。
minimizer: [new UglifyJsPlugin()],
},
}
複製代碼
看了多篇文章以後,肯定是我學不起的內容……只找到一篇相對簡單的文章。
乾貨!擼一個webpack插件(內含tapable詳解+webpack流程)
更深刻的之後再學習……