webpack配置--基础篇

2,267 阅读4分钟

webpack是一个模块打包工具,能够递归构建一个js模块的依赖关系,将模块最终打包成一个或多个文件.

安装

yarn add webpack webpack-cli

零配置

webpack可以进行零配置,只是此时打包功能比较弱.执行:

npx webpack

进行打包. 执行npx webpack默认查找node_modules---bin文件夹--webpack.cmd--执行../webpack/bin/webpack.js

手动配置

简单配置

let path = require('path');
module.exports = {
    mode: 'development', //模式:打包后的文件是否可见production/development
    entry: './src/index.js', // 入口,可以是相对路径
    output: { // 出口
        filename: 'bundle.[hash:8].js', // 打包后的文件名:+哈希(打包生成新的文件), :8指定哈希长度
        path: path.join(__dirname, 'build'), // 打包后的文件路径:必须是绝对路径
    }
};

默认配置文件名为webapck.config.js

webpack-cli文件夹下的config-yarg.js文件指定,配置文件名为webpack.config.js 或 webpackfile.js

修改配置文件名

  • 方法一:
npx webpack --config webpack.config.name.js
  • 方法二: 在package.json文件中配置脚本进行打包, 同时修改配置文件名
"scripts": {
    "build": "webpack --config webpack.config.my.js"
 }
 // 执行 npm run webpack进行打包

当仅在package.json文件中配置脚本进行打包, 在执行命令中修改配置文件名时:

"scripts": {
    "build": "webpack"
 }
// 执行npm run build --  --config webpack.config.my.js 打包,注意两个--进行传参

html文件处理

启动静态服务-webpack-dev-server

webpack-dev-server:启动了一个使用express的Http服务器

// webpack.config.js文件
devServer: { // 开发服务器配置,实现静态服务
    port: 3000, // 服务器启动端口
    progress: true, // 打包进度条
    contentBase: path.join(__dirname, './build'), // 指定静态服务目录
    compress: true, // 是否压缩
}

// package.json文件
"scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server"
}
 
// 执行npm run dev运行静态服务,通过http://localhost:3000在浏览器中访问

html-webpack-plugin

html-webpack-plugin:将打包后的js文件放在html中,将结果放在build目录下

// webpack.config.js文件
let HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
    new HtmlWebpackPlugin({
        template: './src/index.html', // html模板文件
        filename: 'index.html', // 打包后的文件名称
        hash: true, // 添加哈希,避免缓存
        minify: { // 对html也进行压缩
            removeAttributeQuotes: true, // 删除双引号
            collapseWhitespace: true, // 折叠为一行
        }
    }),
],

css文件处理

在html中不能直接引入css文件,因为上文提到html文件只是一个模板;所以,一般是在js文件中引入css文件,引入时需要通过loader进行解析

文件解析

module: {
    rules: [{ 
        // css文件
        test: /\.css$/,
        use: [{
            loader: 'style-loader',
            options: {
                insertAt: 'top', // 将css插入到自定义css的顶部   
            },
        }, 'css-loader'], 
    }, {
        // less文件
        test: /\.less$/,
        use: [style-loader, 'css-loader', 'less-loader'],  
    }],
}
  1. loader特点:功能专一,所以需要多个loader,loader顺序: 从右向左 从上往下执行
  2. css-loader:处理css文件,如解析@import语法等
  3. style-loader:以style标签形式将css代码插入在html页面的head标签,默认插入在head标签的底部;可以通过
  4. less-loader: 将less转为css, yarn add less less-loader

css样式抽离:mini-css-extract-plugin

将所有的css放在head标签中,如果内容过多,导致页面加载阻塞,根据需要将css抽离到单独的文件中.

let MiniCssExtractPlugin = require('mini-css-extract-plugin');
plugins: [
    new MiniCssExtractPlugin({
        filename: 'main.css', // 抽离出的css文件名
    }),
],
module: {
    rules: [{
        test: /\.css$/,
        use: [
            MiniCssExtractPlugin.loader, // 使用此loader将抽离后的css文件路径放在link标签中
            'css-loader',
            'postcss-loader',
        ], 
    }, {
        test: /\.less$/,
        use: [
            MiniCssExtractPlugin.loader,
            'css-loader',
            'postcss-loader',
            'less-loader'
        ],  
    }],
},

css添加前缀: autoprefixer postcss-loader

// 新增postcss.config.js文件
module.exports = {
    plugins: [require('autoprefixer')],
};
// webpack.config.js
use: [
    MiniCssExtractPlugin.loader,
    'css-loader',
    'postcss-loader', // 添加前缀
    'less-loader'
], 

打包css文件: optimize-css-assets-webpack-plugin

使用此插件会对css进行压缩时,必须使用uglifyjs-webpack-plugin,否则js文件不会压缩

let OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
let UglifyJsPlugin = require('uglifyjs-webpack-plugin');
optimization: { // 优化项
    minimizer: [
        new UglifyJsPlugin({
            cache: true,
            parallel: true,
            sourceMap: true,
        }),
        new OptimizeCssAssetsPlugin()
    ]
}

js文件处理

安装babel-loader、@babel/core、@babel/preset-env(es6语法)、@babel/plugin-proposal-class-properties@7.5.5(es7语法)、@babel/plugin-proposal-decorators(装饰器)、@babel/plugin-transform-runtime(修改内置方法或高级语法时使用,抽离部分公共方法)、@babel/runtime(不定)、@babel/polyfill(解析includes方法解析等es7语法) 、eslint(js语句校验规则)

module: {
    rules: [{
        test: /\.js$/,
        use: {
            loader: 'eslint-loader',
            options: {
              enforce: 'pre', // 强制在普通loader之前执行  post在普通loader之后执行
            }
        }, 
        exclude: /node_modules/,
    }, {
        test: /\.js$/,
        use: {
            loader: 'babel-loader', // 转化es6语法
            options: {
                presets: [
                    '@babel/preset-env',
                ],
                plugins: [ // 转化es7语法  注意顺序
                    ["@babel/plugin-proposal-decorators", { "legacy": true }],
                    ["@babel/plugin-proposal-class-properties", { "loose" : true }],
                    "@babel/plugin-transform-runtime"
                ],
            },
        }, 
        exclude: /node_modules/, // 默认会查找所有文件 
        include: path.resolve(__dirname, 'src'),
    }],
},

eslint校验规则: 在eslint.org/demo中配置需要的e…

将jquery注入到每个模块中

通过内联espose-loader将$暴露到window上

import $ from 'expose-loader?$!jquery';
console.log(window.$);
或者
module: {
    rules: [{
        test: require.resolve('jquery'),
        use: 'expose-loader?$',
    }]
}

给每个模块提供$

let webpack = require('webpack');
plugins: [
    new webpack.ProvidePlugin({
        $: 'jquery', // 在每个模块中注入$
    }),
],

此时,不能通过window.$获取

可以直接引入jquery cdn

<script src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script> // 直接引入不打包

此时,通过import $ from 'jquery'时,需要配置externals避免jquery被重新打包.

externals: {
    jquery: '$',
}

图片使用和打包

js文件中使用图片

file-loader: 生成一张图片到build目录下并返回新的图片地址

import img from './640.jpeg'; // 引入图片,返回的结果是一个新的图片地址
let image = new Image();
image.src = img;
document.body.appendChild(image);
// webpack.config.js
module: {
    module: {
    rules: [{
        test: /\.(png|jpg|jpeg|gif)$/,
        use: {
                loader: 'file-loader',
        }, 
    }]
}

css文件中使用图片

background: url('./huaer.jpeg');

可以直接引入,css-loader会对其转为require方式引入

html文件中使用图片

在html文件中直接引入图片时,通过html-withimg-loader对图片文件进行处理

<img src='./huaer.jpeg' /> 
// webpack.config.js
module: {
    rules: [{
        test: /\.html$/,
        use: 'html-withimg-loader',
    }]
}

url-loader

通过url-loader可以将图片转为base64,减少http请求次数.缺点是文件变大

module: {
    rules: [{
        test: /\.(png|jpg|jpeg|gif)$/,
        use: {
            loader: 'url-loader',
            options: {
                limit: 1, // 当图片小于n k时 用base64转换
                outputPath: '/img/', // 输出路径,实现对静态文件分类
                publicPath: 'http://guazi.com', // 当通过cdn方式引入文件时,配置引入路径
            }
        }, 
    }]
}