webpack4-基礎配置

webpack的安裝

安裝本地的webpackcss

yarn add webpack webpack-cli -D
複製代碼

零配置執行

npx webpack         
npx webpack --mode production   // 默認爲生產環境 會進行壓縮打包
npx webpack --mode development
複製代碼

webpack_require 至關因而webpack本身實現的一套模塊化的機制html

手動配置

默認配置文件名稱爲 webpack.config.jsvue

module.exports = {
    mode: 'development',  // 模式 默認兩種 production development
    entry: './src/index.js',  // 入口
    output: {
        filename: 'bundle.[hash:8].js',         // 出口 [hash:8]顯示8位hash值
        path: path.resolve(__dirname, 'build')    // path必須是一個絕對路徑 path.resolve幫咱們把相對路徑解析成絕對路徑
    },
}
複製代碼

在webpack-cli/bin/config-yargs中能夠看到有這樣一行 defaultDescription: "webpack.config.js or webpackfile.js" 即配置文件名稱爲webpack.config.js or webpackfile.js 固然咱們也能夠手動指定配置文件的名稱node

npx webpack --config filename
複製代碼

也能夠經過在package.json中的script裏配置jquery

"scripts":{
    "build": "webpack --config webpack.config.js"   //  webpack.config.js可改成自定義文件名
},
複製代碼
npm run build
複製代碼

若是必定要手動傳參也能夠經過多加兩個-webpack

"scripts":{
    "build": "webpack"   //  webpack.config.js可改成自定義文件名
},
複製代碼
npm run build -- --config webpack.config.js
複製代碼

到目前爲止,咱們的配置依然很弱,只能打包js文件,接下來咱們繼續添加更多的配置es6

下面咱們但願可以經過http://localhost 這樣的方式來啓動一個服務, 咱們能夠經過webpack內置的一個服務 webpack-dev-server (內部是經過express實現的)web

yarn add webpack-dev-server -D
複製代碼

如今咱們能夠經過express

npx webpack-dev-server
複製代碼

固然也一樣能夠經過package.json設置npm

"scripts": {
        "dev": "webpack-dev-server",
        "build": "webpack --config webpack.config.js"
    },
複製代碼

而後執行

npm run dev
複製代碼

同時咱們能夠給在webpack.config.js中對webpack-dev-server進行配置

devServer: {    // 開發服務器的配置
        port: '3000',
        progress: true,
        contentBase: './build',    
        open: true
    },
複製代碼

html插件

指望:動態生成build/index.html, 並把打包後的文件引入到index.html

在src目錄下建index.html,這時咱們須要使用插件HtmlWebpackPlugin,plugin的用法大都相同,HtmlWebpackPlugin是一個類,new一下就能夠了

plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',     // template文件
            filename: 'index.html',            // 生成的template文件名稱 默認爲index.html
            hash: true,                       // 在生成的html中添加引用hash
            minify: {
                removeAttributeQuotes: true,  // 去除雙引號
                collapseWhitespace: true,     // 去除空行
            }
        }),
    ],
複製代碼

到這裏能夠看到咱們既能夠經過在配置output的時候經過filename: bundle.[hash:8].js 來給生成文件添加hash,也能夠經過HtmlWebpackPlugin的配置hash來實現,二者添加hash的方式分別爲 bundle.12345678.js和 bundle?12345678

而經過filename: bundle.[hash:8].js這種方式實現,咱們還須要再作一步,就是在每次從新打包的時候把舊的文件刪除 // todo

樣式處理

咱們知道,webpack默認只支持js模塊,那麼咱們怎麼處理css/less/scss等模塊呢?這時候就須要loader上場了

You may need an appropriate loader to handle this file type.
複製代碼
module: {           // 模塊
        rules: [    // 規則
            // css-loader 主要用來解析@import這種語法 
            // style-loader 把樣式插入頁面
            // loader特色,功能單一 多個loader能夠協做
            // 一個loader可使用字符串,多個可使用數組, 須要傳入參數時可使用對象方式
            // loader的順序,默認爲從右向左, 從下到上執行 webpack選擇了compose方式
            // { 
            // test: '/\.css$/', use: [
            // { loader: 'css-loader', options: {} } // 對象方式
            // ]
            // },
            { test: /\.css$/, use: ['style-loader', 'css-loader'] },
        ]
    },
複製代碼

less、sass文件同理, 以scss文件爲例:

{
    test: /\.css$/, use: [
        { loader: 'style-loader', options: { insertAt: 'top' } },        // 對象方式 insertAt插入位置
        { loader: 'css-loader', options: {} },
    ]
},
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
複製代碼

css抽離

webpack4中,css抽離須要插件 mini-css-extract-plugin (注意再也不是extract-text-webpack-plugin)

new miniCssExtractPlugin({
    filename: 'main.css',   // 抽離出的css的文件名
}),
複製代碼

同時在module.rules中作以下修改以免重複插入:

- // { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
+ { test: /\.scss$/, use: [miniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] },
複製代碼

自動添加前綴

咱們可使用postcss-loader autoprefixer來實現

- // { test: /\.scss$/, use: [miniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] },

+ { test: /\.scss$/, use: [miniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'] },
複製代碼

在根目錄下新建postcss.config.js

module.exports = {
    plugins: [
        require('autoprefixer'),    // 自動添加前綴
    ]
}
複製代碼

壓縮

此時咱們設置mode爲production,發現js和html都已是壓縮過的了,但是css文件卻沒有。咱們這裏引入另一個插件:optimize-css-assets-webpack-plugin來優化css資源

let OptimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [       
        ...,                        
        new OptimizeCss(),
]
複製代碼

固然咱們也能夠經過uglifyjs-webpack-plugin來壓縮咱們的js文件

let UglifyjsPlugin = require('uglifyjs-webpack-plugin');
plugins: [       
        ...,                        
        new UglifyjsPlugin(),
]
複製代碼

es6

咱們但願打包後的文件能夠把es6語法轉爲es5,能夠經過babel-loader幫咱們實現

// src/a.js
console.log('this is a');

const fn = () => {
    console.log('fn');
}
複製代碼

安裝babel依賴模塊

yarn add babel-loader @babel/core @babel/preset-env -D
複製代碼
{
    test: /\.js|jsx$/, use:
    {
        loader: 'babel-loader', options: {
            presets: ['@babel/preset-env']
        }
    }
},
複製代碼

es7

如今寫es6的語法沒有問題了,可是咱們有可能用到es7的語法, 好比類的寫法,這時候咱們還須要藉助一個插件:@babel/plugin-proposal-class-properties 又好比裝飾器的寫法,咱們能夠藉助@babel/plugin-proposal-decorators來實現

{
    test: /\.js|jsx$/, use:
    {
        loader: 'babel-loader', options: {
            presets: ['@babel/preset-env'],
            plugins: [
                ["@babel/plugin-proposal-decorators", { "legacy": true }],  // 支持es7的裝飾器的寫法 要放在前面
                '@babel/plugin-proposal-class-properties',       // 支持es7的類的寫法 
            ]
        }
    }
},
複製代碼

這裏須要注意的是@babel/plugin-proposal-decorators要放在@babel/plugin-proposal-class-properties前面。

es6新的API

babel只會幫咱們把es6新的語法轉成es5,可是對於新的API如:promise, generater 等咱們還須要藉助一個包 @babel-polyfill(可是比較大) 同時咱們能夠藉助一個插件--@babel/plugin-transform-runtime 作了必定優化,如代碼抽離

js語法校驗 eslint

yarn add eslint eslint-loader
複製代碼
{
    test: /\.js|jsx$/,
    use: {
        loader: 'eslint-loader',
        options: {
            enforce: 'pre', // pre post 
        }
    }
},
複製代碼

接下來就可使用本身配置好的.eslintrc.json文件(放在根目錄下),固然咱們也能夠到eslint官網,手動進行配置,而後下載eslintrc.json,只要加個.就好了。

全局變量的引入

  1. 簡單粗暴
import $ from 'jquery';
    console.log($)  
    console.log(window.$) // undefined
複製代碼
  1. 內聯loader expose-loader 暴露到全局的loader,用法以下:
import $ from 'expose-loader?$!jquery';
console.log($)  
console.log(window.$) // undefined
複製代碼
  1. webpack expose-loader 只能經過window訪問
{
    test: require.resolve('jquery'),
    use: 'expose-loader?$'
},

// index.js
console.log(window.$)  
複製代碼
  1. webpack內置插件
let webpack = require('webpack');

new webpack.ProvidePlugin({     // 在每一個模塊中都注入$
    $: 'jquery',
}),

// index.js
console.log($);         // 均可以訪問
console.log(window.$)  
複製代碼
  1. cdn引入+webpack
externals: {    // 外部引入,不須要打包
    jquery: '$',
},

// index.js
import $ from 'jquery';     // 雖然引入可是不會再打包
console.log($);
複製代碼

圖片處理

咱們使用圖片的場景有兩種:

  1. 在js中建立圖片來引用
  2. 再css中使用,background
  3. img標籤的使用
// index.js
let img = new Image();
img.src = require('./logo.png');
document.body.appendChild(img);
複製代碼

這時咱們須要藉助 file-loader 了

{
    test: /\.png|jpg|gif|jpeg$/,
    loader: 'file-loader',
    options: {

    }
},
複製代碼
// index.js
import logo from './logo.png';  // 返回一個新的文件 好處是能夠重命名圖片

let img = new Image();
img.src = logo;
document.body.appendChild(img);

// a.css
body{
    color: yellow;
    background: url('./logo.png') no-repeat;
}

複製代碼

ok,發現前兩種都沒有什麼問題,但是第三種直接寫在html中的卻不行

<body>
    <img src='./logo.png' alt=""/>
    <!-- 模版 -->
</body>
複製代碼

處理直接寫在html裏的圖片,還須要用到另外一個loader:

{
    test: /\.html/,
    use: 'html-withimg-loader'
},
複製代碼

從新啓動就行了。

文件打包分類

若是想要作更多的限制呢,好比說對打包圖片大小的限制打包成base64以減小http請求(base64會比源文件大1/3左右),咱們可使用 url-loader

{
    test: /\.png|jpg|gif|jpeg$/,
    loader: 'url-loader',
    options: {
        limit: 4 * 1024,        // 圖片大小限制值
        outputPath: '/img/',     // 輸出目錄
        publicPath: 'http://58.com'     // 添加打包後的圖片域名
    }
},
複製代碼

打包多頁面應用

基本配置以下:

let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        home: './src/index.js',
        other: './src/other.js',
    },
    output: {
        filename: '[name].js',               // name爲變量,根據entry的命名生成對應打包後的文件名稱
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [
        new HtmlWebpackPlugin({             // 這裏須要new多個HtmlWebpackPlugin
            template: './src/index.html',
            filename: 'home.html',
            chunks: ['home']                // html依賴,決定了打包後的哪些文件插入該模版中, 能夠寫多個,且有順序
        }),
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'other.html',
            chunks: ['other', 'home']
        }),
    ],
}
複製代碼

配置source-map

// devtool: 'source-map', // 增長映射文件 會單獨生成一個sourcemap文件,出錯了會標示當前出錯的列和行 特色 大 全
    devtool: 'eval-map',
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'home.html',
        }),
    ],
複製代碼

watch用法

output: {
        filename: '[name].js',               // name爲變量,根據entry的命名生成對應打包後的文件名稱
        path: path.resolve(__dirname, 'dist'),
    },
    watch: true,    // 實時編譯打包
    watchOptions: { // 監控選項
        poll: 1000, // 每秒訪問多少次
        aggregateTimeout: 500, // 防抖
        ignored: /node_modules/
    },
複製代碼

插件使用

  • CleanWebpackPlugin 每次打包刪除dist
  • CopyWebpackPlugin // copy文件目錄
  • BannerPlugin // 給打包後的文件添加頭註釋
plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'home.html',
        }),
        new CleanWebpackPlugin('./dist'),   // 傳入要刪除的目錄 也可傳數組
        new CopyWebpackPlugin([{ from: './src/static', to: './dist' }]),   //須要拷貝的目錄 必須是arr
        new webpack.BannerPlugin('make 2019 by beth.miao'),
    ],
複製代碼

webpack跨域問題 配置代理 proxy

proxy: {
            '/api': {
                target: 'http://localhost:3001',
                pathRewrite: { '/api': '' }
            }
        }
複製代碼

resolve 屬性的配置

resolve: {  // 解析第三方包 common
        modules: [path.resolve('node_modules')],
        // mainFields: ['style', 'main'],
        // mainFiles: '',
        alias: {
            bootstrap: 'bootstrap/dist/css/bootstrap.css',
        },
        extensions: ['.js', '.css', '.json', 'vue'],    // 引入路徑後綴名處理
    },
複製代碼
相關文章
相關標籤/搜索