webpack4配置之——08:初步优化开发环境

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kai_vin/article/details/88700172

如果你喜欢这系列的文章,欢迎star我的项目,源码地址,点击这里

优化项

  • 开发调试所用的 sourcemap

  • js 文件增加 hash 值,方便缓存

  • 配置模块热更新

增加 sourcemap

开发过程中,代码出错是难免的,那么调试就很重要了,webpack 帮我们打包所有文件,省了我们很多事情,但打包后的代码,却不适合用来调试,可以通过在 webpack 中增加 devtool 配置,来向浏览器暴露我们的源码,让我们可以在源码的基础上,进行调试

webpack.dev.conf.js 中,增加如下配置:

// 开发工具
devtool: 'eval-source-map',

这样代码哪里错了,可以看到是在源码的哪里,而不会因为编译后报错,却找不到具体是哪里出错

devtool 有很多种值可选,这里只是其中的一种,可自行百度了解~

增加缓存机制

此前,我们的出口文件 bundle.js是一个固定的名字,如果项目上线后,用户缓存了该文件,而后期我们修改了文件,用户却已经缓存过该文件,从而无法获取最新,这时候,我们就需要通过 hash 值来确保,只要文件更新了,hash 值发生变化,文件名就会不同,用户会缓存新的文件,从而达到获取最新

那么这里就需要修改 webpack.dev.conf.js 文件的出口配置了:

// 输出文件配置项
output:{
    path:path.resolve(__dirname,"dist"),
    filename: 'js/[name].[hash].js',
    chunkFilename: 'js/[name].[chunkhash].js',
    publicPath:""
},

执行命令 npm start 查看效果,页面能正常显示,打开开发者工具,可发现,引入的 js 文件,已经不叫 bundle.js 了,而变成了 main 开头加一段 hash 值的一个文件,这个 mainwebpack 默认的出口文件名,要想这里也可控,只需修改入口文件配置即可

// 入口文件配置项
entry:{
    app:[path.resolve(__dirname, 'src/index.js')],
},

再执行命令 npm start 查看效果,是不是已经变成了我们设置的 app 这个名字?~

增加模块热更新

现阶段我们每次修改页面,页面都会自动整体刷新,但是现在不想刷新整个页面,而是改了哪里,就刷新哪里

需要修改 webpack.dev.conf.js 文件的 plugins 以及 devServer 的配置

// 插件配置项
plugins: [
    new HtmlWebpackPlugin({
        filename: 'index.html',//输出文件的名称
        template: path.resolve(__dirname, 'src/index.html'),//模板文件的路径
        title:'webpack-主页',//配置生成页面的标题
    }),
    new webpack.HotModuleReplacementPlugin()
],

// 开发服务配置项
devServer: {
    port: 8080,
    contentBase: path.resolve(__dirname, 'dist'),
    historyApiFallback: true,
    host: ip,
    overlay:true,
    hot:true,
    inline:true,
    after(){
        open(`http://${ip}:${this.port}`)
        .then(() => {
            console.log(chalk.cyan(`http://${ip}:${this.port} 已成功打开`));
        })
        .catch(err => {
            console.log(chalk.red(err));
        });
    }
}

上面我们在 plugins 配置中引用了一个插件,这个插件是依托的 webpack 所以我们需要在文件头部引入 webpack

const webpack = require("webpack");

接下来,我们还需要修改 src/index.js 文件,当局部模块更新时,通知该文件

import './css/reset.css';
import './scss/public.scss';
import './less/index.less';

import image from './images/favicon.png';

if (module.hot) {
    module.hot.accept();
}

var func = str => {
    document.getElementById('app').innerHTML = str;
};
func('我现在在使用 es6 新语法-箭头函数!');

document.getElementById('postcss').innerHTML = "<h1>我自动添加了浏览器前缀</h1><img src='"+ image +"'/><span class='icon iconfont icon-toPay'></span>";

增加的代码为:

if (module.hot) {
    module.hot.accept();
}

这段代码需要放在引入下面,页面代码上面~

到此模块热更新算是初步配置完成了,现在执行命令 npm start 然后修改样式,或者入口文件内编译的内容,看看浏览器,已经不会去刷新整个页面了,而是哪里涉及到修改,就刷新哪里

相关文件配置信息更新情况

以下为本文已涉及到的配置文件的当前详细信息

  1. webpack.dev.conf.js 文件现在的配置信息情况:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const open = require('opn');//打开浏览器
const chalk = require('chalk');// 改变命令行中输出日志颜色插件
const ip = require('ip').address();

module.exports = {
    // 入口文件配置项
    entry:{
        app:[path.resolve(__dirname, 'src/index.js')],
    },
    // 输出文件配置项
    output:{
        path:path.resolve(__dirname,"dist"),
        filename: 'js/[name].[hash].js',
        chunkFilename: 'js/[name].[chunkhash].js',
        publicPath:""
    },
    // 开发工具
    devtool: 'eval-source-map',
    // webpack4.x 环境配置项
    mode:"development",
    // 加载器 loader 配置项
    module:{
        rules:[
            {
                test: /\.css$/,
                use: [{
                        loader: 'style-loader'
                    },{
                        loader: 'css-loader'
                    },{
                        loader: 'postcss-loader',
                        options: {
                            sourceMap: true,
                            config: {
                                path: 'postcss.config.js'
                            }
                        }
                    }
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    {
                        loader: 'style-loader', 
                    },
                    {
                        loader: 'css-loader', 
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            sourceMap: true,
                            config: {
                                path: 'postcss.config.js'
                            }
                        }
                    },
                    {
                        loader: 'sass-loader', 
                        options: { sourceMap: true }
                    }
                ],
                exclude: /node_modules/
            },
            {
                test: /\.less$/,
                use: [
                    {
                        loader: 'style-loader', 
                    },
                    {
                        loader: 'css-loader', 
                        options: {
                            importLoaders: 1,
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            sourceMap: true,
                            config: {
                                path: 'postcss.config.js'
                            }
                        }
                    },
                    {
                        loader: 'less-loader', 
                        options: { 
                            sourceMap: true,
                        }
                    }
                ]
            },
            {
                test: /\.(png|jp?g|gif|svg)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 8192,        // 小于8192字节的图片打包成base 64图片
                            name:'images/[name].[hash:8].[ext]',
                            publicPath:''
                        }
                    }
                ]
            },
            {
                // 文件依赖配置项——字体图标
                test: /\.(woff|woff2|svg|eot|ttf)$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        limit: 8192, 
                        name: 'fonts/[name].[ext]?[hash:8]',
                        publicPath:''
                    },
                }],
            }, {
                // 文件依赖配置项——音频
                test: /\.(wav|mp3|ogg)?$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        limit: 8192, 
                        name: 'audios/[name].[ext]?[hash:8]',
                        publicPath:''
                    },
                }],
            }, {
                // 文件依赖配置项——视频
                test: /\.(ogg|mpeg4|webm)?$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        limit: 8192, 
                        name: 'videos/[name].[ext]?[hash:8]',
                        publicPath:''
                    },
                }],
            }, {
                test:/\.html$/,
                use:[
                    {
                        loader:"html-loader",
                        options:{
                            attrs:["img:src","img:data-src"] 
                        }
                    }
                ]
            }
        ]
    },
    // 插件配置项
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',//输出文件的名称
            template: path.resolve(__dirname, 'src/index.html'),//模板文件的路径
            title:'webpack-主页',//配置生成页面的标题
        }),
        new webpack.HotModuleReplacementPlugin()
    ],
    // 开发服务配置项
    devServer: {
        port: 8080,
        contentBase: path.resolve(__dirname, 'dist'),
        historyApiFallback: true,
        host: ip,
        overlay:true,
        hot:true,
        inline:true,
        after(){
            open(`http://${ip}:${this.port}`)
            .then(() => {
                console.log(chalk.cyan(`http://${ip}:${this.port} 已成功打开`));
            })
            .catch(err => {
                console.log(chalk.red(err));
            });
        }
    }
}

猜你喜欢

转载自blog.csdn.net/kai_vin/article/details/88700172