基於webpack4.x項目實戰1-簡單使用javascript
基於webpack4.x項目實戰2 - 配置一次,多個項目運行css
基於webpack4.x項目實戰3 - 手寫一個clihtml
webpack在前端開發者的世界再熟悉不過了,網上也不少關於webpack的文章,本身也寫一下,加深印象前端
webpack 是js模塊打包器,一直在更新,本文是基於webpack4.29.5版本,未來的某一天,發覺本文章的一些配置用不了,那多是webpack已經更新到更高的版本了vue
安裝webpack4
和webpack-cli
,因爲webpack4中和webpack-cli抽離了,因此須要分別安裝,咱們全局安裝一個:java
npm install webpack webpack-cli -g
node
搞一個demo試試react
mkdir webpack-demo && cd webpack-demo
npm init -y
複製代碼
新建一個index.js文件,./src/index.jswebpack
--package.json
--src
-- index.js
複製代碼
webpack4支持0配置,默認./src/index.js
爲入口文件,webpack運行時,會根據mode的值採起不一樣的默認配置,mode兩個可選值:production
和 development
。沒有傳mode,會有一個警告css3
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
複製代碼
解決這個警告,修改package.json
部分,傳入mode便可
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
複製代碼
development
和production
的區別在於一個代碼沒壓縮,一個有壓縮和優化,執行 npm run dev
,就會生產一個./dist/main.js
文件。
若是咱們只是想要一個簡單的打包功能,使用默認配置就夠用了。都不須要建立webpack.config.js
在咱們的項目中,使用webpack的默認配置明顯是不夠用的,仍是須要自定義咱們的webpack配置
在咱們的項目根目錄,建立webpack.config.js
,webpack配置的概況以下
module.exports = {
entry: '', // 入口文件
output: {}, // 出口文件
module: {}, // 模塊相關配置
plugins: [], // 插件相關配置
resolve: { } // 解析模塊的可選項
devServer: {}, // 開發服務器相關配置
devtool: 'inline-source-map', //開發工具,好比啓動source-map
mode: 'development' // 模式配置 development/production
}
複製代碼
接下來,咱們一點點往裏面添加內容,以此更好的理解webpack
一些項目中,只有一個入口文件,那麼,入口文件和出口文件能夠這樣配置
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js', // 打包後的文件名稱
path: path.resolve(__dirname, 'dist') // 打包後的目錄
}
}
複製代碼
若是有多個入口,能夠將entry配置成一個array或者object,若是是array,則是將多個入口文件最終生成一個出口文件,若是是object,則對應生成多個文件,以下: entry爲array
const path = require('path');
module.exports = {
entry: ['./src/a.js', './src/b.js'], 多個入口文件打包爲一個js文件
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
}
}
複製代碼
entry爲object
const path = require('path');
module.exports = {
entry: {
a: './src/a.js',
b: './src/b.js'
},
output: {
filename: '[name].js', // 打包後爲a.js和b.js文件
path: path.resolve(__dirname, 'dist')
}
}
複製代碼
因爲webpack只能處理js,當咱們須要處理其餘非js文件時,咱們須要引入對應的loader
咱們想從javaScript 模塊中 import 一個 CSS 文件,須要在 module 配置中 安裝並添加 style-loader
和 css-loader
:
npm install style-loader css-loader -D
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
複製代碼
src/css/style.css
body {
background: red;
}
複製代碼
src/index.js
import './css/style.css';
複製代碼
打開index.html,能夠看到咱們頁面的背景色此時爲紅色。執行編譯,css文件將會打包到js文件當中
加載圖片,也須要安裝對應的loader npm install file-loader url-loader -D
在css引入背景圖片時,須要指定一下相對路徑
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/, // 加載圖片
use: [{
loader: 'url-loader',
options: {
limit: 8192, // 小於8k的圖片自動轉成base64格式
name: 'images/[name].[ext]?[hash]', // 圖片打包後存放的目錄
publicPath: '../' // css圖片引用地址,可修正打包後,css圖片引用出錯的問題
}
}]
},
]
}
複製代碼
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
}
複製代碼
webpack提供了各類各樣的插件,下面介紹幾種經常使用的插件,只試過在webpack4.0以上的版本,其餘版本沒試過,因此若是有報錯,那多是版本不支持
使用webpack插件,咱們要寫在配置中的plugins裏面,在使用插件以前,咱們都須要先安裝該插件。下面介紹幾個經常使用的插件
該插件的做用爲:生成html頁面,自動引入js文件,自動消除src引入的緩存問題,上線以前壓縮。
使用前安裝該插件npm install html-webpack-plugin --save -dev
;
let HtmlWebpackPlugin = require('html-webpack-plugin');
module: {
...
plugins:[
new HtmlWebpakPlugin({
minify:{
collapseWhitespace: true, // 摺疊空白區域 也就是壓縮代碼
removeAttributeQuotes: true // 移除雙引號,
},
hash:true, //向html引入的src連接後面增長一段hash值,消除緩存
template:'./src/index.html', // 模板地址
title: 'webpack' // 標題
})
]
}
複製代碼
關於該插件的更多使用方法,能夠看這裏
前面安裝的css-loader
在js中引入css文件時,打包後的css是和js混合在一塊兒的,若是咱們想打包後的css文件時單獨的存在,須要引入這個插件。
安裝npm i extract-text-webpack-plugin@next -D
,其中@next表示能夠在webpack4中使用
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("css/styles.css"), // 打包後的css文件
]
}
複製代碼
關於該插件的更多使用方法,能夠看這裏
利用postcss中的autoprefixer來爲css3自動添加前綴。
安裝npm i postcss-loader autoprefixer -D
在根目錄下新建postcss.config.js
裏面寫入
module.exports = {
plugins: [
require('autoprefixer')
]
}
複製代碼
webpack.config.js裏面,配置postcss-loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
}
]
}
}
複製代碼
在package.json上,添加須要支持的版本
"browerslist": [
"last 2 versions",
"IE 8",
"UCAndroid"
],
複製代碼
webpack提供的插件很是多,更多的插件,能夠看這裏
安裝npm i -D @babel/core @babel/plugin-transform-runtime @babel/preset-env babel-loader
在webpack.config.js中添加
..略
module:{
rulse:[
...略
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/, // 忽略掉該文件下的js
}
]
}
複製代碼
在根目錄下,也就是和webpack.config.js同一個目錄下,新增.babelrc文件
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime"]
}
複製代碼
webpack-dev-server
爲自動刷新和模塊熱替換機制,裝上它,能夠咱們的改動能夠自動刷新
安裝npm install webpack-dev-server -D
修改一下咱們的webpack.config.js
var path = require('path');
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'dist'), // 服務器資源的根目錄,不寫的話,默認爲bundle.js
compress: true, // 服務器資源採用gzip壓縮
port: 9000, // 運行的端口
overlay: true // 出錯代碼是否顯示在html頁面上
hot: true //熱加載
}
};
複製代碼
再修改咱們的package.json
...
"scripts": {
"dev": "webpack-dev-server --mode development --open",
}
...
複製代碼
執行npm run dev
,就會自動打開瀏覽器,監聽你的修改了
注意點:
webpack-dev-server
輸出的文件只存在於內存中,不輸出真實的文件,也就是說,你啓動它,你的dist文件實際上是沒有生產新的文件的
resolve是webpack自帶的,主要做用是設置模塊如何被解析 主要介紹幾個:
resolve.alias配置項經過別名來把原來導入路徑映射成一個新的導入路徑,例如:
resolve: {
alias: {
components: './src/components/'
}
}
複製代碼
這樣,咱們原來import Dialog from './src/components/dialog'
能夠縮減爲import Dialog from 'components/dialog'
;
resolve: {
extensions: ['.js', '.json']
}
複製代碼
咱們用import data from './data'
時,webpack就會依次尋找data.js是否存在,不存在繼續尋找data.json是否存在,最後尋找data/index.js是否存在
Webpack找第三方模塊,默認是隻會去node_modules
目錄下尋找。若是你的項目中,不少模塊要引用這個目錄下的, 那目錄可能很長。打個比方,src/components/test.js要去node_modules
下面找dialog組件,那麼可能這樣寫:import '../../../components/dialog'
,利用resolve.modules
優化後:
resolve.modules:['./src/components','node_modules']
複製代碼
你能夠簡單經過 import 'dialog'
導入。
經過以上的介紹,咱們大概熟悉了webpack的一些基礎配置,下面咱們來進入實戰
咱們配置具備以下功能的webpack配置:
咱們目錄結構以下:
——src
├─components
├─css
└─images
├─index.js
——index.html
——.babelrc
——package.json
——postcss.config.js
——webpack.config.js
複製代碼
webpack.config.js的配置以下:
const path = require('path');
const htmlWebpackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'main.js', // 打包後的文件名稱
path: path.resolve(__dirname, 'dist') // 打包後的目錄
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({ // 拆分單獨的css文件
fallback: "style-loader",
use: ['css-loader', 'postcss-loader'] // 加載css
})
},
// 加載less
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ['css-loader', 'postcss-loader']
})
},
{
test: /\.(png|svg|jpg|gif)$/, // 加載圖片
use: [{
loader: 'url-loader',
options: {
limit: 8192, // 小於8k的圖片自動轉成base64格式
name: 'images/[name].[ext]?[hash]', // 圖片打包後的目錄
publicPath: '../' // css圖片引用地址
},
}]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/, // 加載字體文件
use: [
'file-loader'
]
},
// 轉義es6
{
test: /\.js$/,
loader: 'babel-loader',
include: /src/, // 只轉化src目錄下的js
exclude: /node_modules/, // 忽略掉node_modules下的js
}
]
},
resolve: {
alias: {
components: path.resolve(__dirname, 'src/components/') // 別名
},
extensions: ['.js', '.json'], // 忽略文件後綴
modules: ['node_modules']
},
plugins: [
new htmlWebpackPlugin({
template: "./index.html",
filename: "index.html",
inject: true,
hash: true,
chunksSortMode: 'none' //如使用webpack4將該配置項設置爲'none'
}),
new ExtractTextPlugin("css/styles.css"),
new OptimizeCssAssetsPlugin({ // 優化css
cssProcessor: require('cssnano'), //引入cssnano配置壓縮選項
cssProcessorOptions: {
discardComments: { removeAll: true }
},
canPrint: true //是否將插件信息打印到控制檯
})
],
devServer: {
hot: true,
contentBase: path.join(__dirname, 'dist'),
port: 3002,
},
};
複製代碼
代碼地址: 這裏
目前vue、react都有本身的webpack配置,都已經配好了,直接拿來用便可。不過做爲一個優秀的前端,咱們也須要知道如何從零開始配置屬於本身的webpack.config.js。 後續寫一個只需配置一次,能夠多個項目公共的webpack配置,敬請期待...
參考文章: