# webpack基础配置大纲

# 配置开发服务器

我们可以通过webpack-dev-server来配置我们的开发服务器




 





module.exports = {
    devServer: {
        port: 3000, //服务的默认端口号
        progress: true, //是否开启进度条
        contentBase: './dist', //以哪个目录作为静态资源目录
        compress: true, //启动gzip压缩
    }
}

然后配一个脚本




 

// package.json
"scripts": {
"dev": "webpack-dev-server"
},

这样我们就可以通过npm run dev启动我们的开发服务器

# 配置html-webpack-plugin

我们希望每次打包出来的文件中除了bundle.js还需要有一个index.html,并且这个index.html中引入了我们的bundle.js, 我们可以通过插件html-webpack-plugin来解决这个问题




 








plugins: [
    new HtmlWebpackPlugin({
        template: './src/index.html', //模板文件目录
        filename: 'index.html', // 打包生成html文件名
        minify: {
            removeAttributeQuotes: true, // 删除打包出的html文件中的双引号
            collapseWhitespace: true, // 将打包出来的html文件压缩成一行
        },
        hash: true, //添加hash值 解决缓存问题
    })
]

除了在html-webpack-plugin设置引入js文件的hash值,我们还可以在输出配置里面自己设置生成js文件的hash值




 

output: {
    filename: 'bundle.[hash:8].js', //打包后的文件名,生成的文件带hash值,并且只显示8位hash
    path: path.resolve(__dirname, 'dist'), //路径必须是绝对路径
},

这样处理之后我们html中引入的js文件名是这样的



<script type=text/javascript src=bundle.0e110d78.js?0e110d78a69112b25b93></script>

# 处理样式文件

# 处理.css文件和.less文件

默认我们的webpack只可以处理js文件,我们需要一些loader让我们的webpack可以处理一些.css .less文件等



npm i style-loader css-loader less-loader

我们先大致了解一下这3个loader的作用




 
style-loader // 生成style标签插入到index.html中
css-loader // 处理一些@import './a.css'语法
less-loader // 将less语法转化为css语法

我们来看下怎么配置这些loader




 


























module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                {
                    loader: 'style-loader'
                },
                {
                    loader: 'css-loader'
                }
            ]
        },
        {
            test: /\.less$/,
            use: [
                {
                    loader: 'style-loader'
                },
                {
                    loader: 'css-loader'
                },
                {
                    loader: 'less-loader'
                }
            ]
        }
    ]
}

首先loader的执行顺序是从下到上,从右到左

我们首先通过特定的规则匹配到对应的.css文件或者.less文件,然后按照先后的顺序调用对应的loader进行处理

# 抽离css文件

如果项目中不想使用这种插入style标签的形式,希望把css样式都抽离成一个css文件,我们需要借助一个插件mini-css-extract-plugin




 



const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'main.css', //生成的css文件名
        })
    ],

然后我们不在使用style-loader




 
















module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader'
            ]
        },
        {
            test: /\.less$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                'less-loader'
            ]
        }
    ]
}

但是我们够可以发现生成的css文件没有进行压缩,同样的我们需要个插件来帮助一下optimize-css-assets-webpack-plugin




 



const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
    optimization: {
        minimizer: [new OptimizeCSSAssetsPlugin({})],
    },
}

这样的话就可以在生产模式下对打包出来的css文件进行压缩了,但是会发现一个问题,我们的js文件又不压缩了

我们需要另外一个插件terser-webpack-plugin




 



const TerserJSPlugin = require('terser-webpack-plugin');
module.exports = {
    optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
    },
}

# 自动添加兼容前缀

我们可以通过postcss-loaderautoprefixer让我们的css代码自动添加一些兼容的前缀




 





{
    test: /\.css$/,
    use: [
        MiniCssExtractPlugin.loader,
        'css-loader',
        'postcss-loader'
    ]
},

我们只需要在css-loader使用之前使用post-loader就好了,但是我们还需要写一个配置文件




 

// postcss.config.js
module.exports = {
    plugins: [require('autoprefixer')]
}

这样我们就可以自动补充浏览器前缀了

# 转化高版本js语法

在项目中我们经常使用一些es6 es7等高级语法,所以需要转化为es5的语法

我们需要下载一些包



npm i babel-loader @babel/core @babel/preset-env  @babel/plugin-proposal-class-properties

然后进行配置




 












{
    test: /\.js$/,
    use: {
        loader: 'babel-loader',
        options: {
            presets: [
            '@babel/preset-env'
            ],
            plugins: [
                '@babel/plugin-proposal-class-properties'
            ]
        }
    },
    exclude: /node_modules/
},

还有一些更高级的语法啥的就不记录怎么做处理了,谷歌cv一下就好了

# 全局变量引入问题

在一些老的项目需要或者依赖于jquery,所以我们需要把$挂载到window上或者注入到每一个模块中

我们先来看下通过expose-loader$挂载到window




 





module: {
    rules: [
        {
            test: require.resolve('jquery'),
            use: 'expose-loader?$'
        },
    }
}

或者我们不想通过window.$这样的写法,我们希望直接使用$而不需要import $ from 'jquery',这个时候我们需要在每个模块中注入一个$,这个实现webpack给我们提供了一个插件




 

const webpack = require('webpack')
new webpack.ProvidePlugin({
    $: 'jquery'
})

看自己的需求来决定使用哪种方法吧

# 配置打包图片

在项目中我们使用图片的方式有3种

  • 在js中创建图片来引入 我们需要使用file-loader来处理这类问题



 

{
    test: /\.(png|jpg|gif)$/,
    use: 'file-loader'
},

并且在js文件中我们需要这样引入图片




 
import logo from './123.jpg'
const image = new Image()
image.src = logo
  • 在css中引入 background('url') 在css中引入和普通的引入一样就好了,因为css-loader会将语法进行转换


background('./123.jpg') => background(require('./123.jpg'))
  • 在html中引入() 在html文件中引入的图片我们需要借助一个html-withimg-loader



 

{
    test: /\.html$/,
    use: 'html-withimg-loader'
}