欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用一个hello world项目学习webpack

程序员文章站 2022-05-08 13:36:35
...

更多内容欢迎来到博客 :https://imjianjian.github.io

项目准备

项目地址

项目结构

- src
    - app
        - App.vue
    - img
        - logo.png
    - style
        - app.scss
    - index.html
    - main.js

webpack基本概念

entry

即webpack打包的入口js文件,可以根据项目实际情况配置成但入口或者多入口,webpack会根据入口文件内的引入的文件绘制依赖图,将该模块和模块对应的依赖都打包到一个文件中。

//单入口
const config = {
    entry:'a.js'
}
//多入口
const config = {
    entry:{
        a:'a.js',
        b:['b1.js','b2.js']  //多个文件打包为一个文件
    }
}

output

即webpack打包后的输出,即使此时的entry中存在多个入口,也只提供单一的输出配置。

//单一入口情况,一下将所有文件都打包到dist/bundle.js里
const config = {
    output:{
        filename:'bundle.js',
        path:path.join(__dirname,'dist')
    }
}
//多入口情况
const config ={
    output:{
        filename:'[name].js',
        path:path.join(__dirname,'dist')
    }
}

这里的输出文件名中可以使用[name],[hash],[chunkhash]等占位,这样输出的文件名中就有带有资源hash值。[hash]是本次打包所有资源的hash值,同义词打包的文件得到的hash是一样的,而[chunkhash]是单个文件打包的hash值,每个文件且每次打包都不相同。还可以使用[hash:8]来取hash值得位数

Loader

webpack是一个js bundler,如果需要它对非js得模块,例如typeScript,sass,less,vue等模块进行打包,则需要对应的loader进行转换。而且同一种资源有时需要使用不止一种loader。

const config ={
    module:{
        rules:[
            {
                test: /\.vue$/, 
                use: [{loader: 'vue-loader'}]
            },
            {
                test:/\.scss/,
                use:[
                    {loader:'style-loader'},
                    {
                        loader:'css-loader',
                            options: {
                                modules: true
                            }
                    },
                    {loader:'sass-loader'}
                ]
            }
        ]
    }
}

在rules数组中的每一项都是一种模块类型的转换规则,test参数匹配对应后缀的文件,use数组中配置对应使用的loader以及配置loader的其他参数。

官方推荐的loader

Plugins

plugins用于解决其他loader无法做到的事情,比如压缩资源,启动开发服务器等等。

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

const config ={
    plugins:[
        new webpack.optimize.UglifyJsPlugin(),
        new HtmlWebpackPlugin({
            template:path.join(__dirname,'src/index.html')
        })
    ]
}

plugins数组的每一项就是一个插件

webpack自带的以及推荐使用的Plugins

webpack配置文件结构

webpack默认的配置文件名为webpack.config.js,当然也可以自定义其他文件名,只要在webpack –config filename命令中修改filename为当前的配置文件即可。

完整的webpack配置参数可以查看官方文档

开发模式和打包模式(Dev&Build)

可以通过命令行向webpack闯入参数,以判断使用开发模式还是打包。

在package.json中配置npm script:

  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "dev": "cross-env NODE_ENV=develement webpack-dev-server --config webpack.config.js"
  }

命令行中使用了cross-env用于跨平台地设置及使用环境变量,具体的参照官方github说明

在build和dev中我们分别向webpack传入了不同的NODE_ENV参数值。在webpacl配置文件中,可以使用process.env.NODE_ENV来的到这个值,以便判断该运行那哪个模式。

webpack-dev-server

在webpack中用devServer参数来配置它,在此之前我们需要先判断是否运行在开发模式

var WebpackDevServer = require('webpack-dev-server');

//获得NODE_ENV参数,用于判断处于开发模式还是打包模式
var isDev = process.env.NODE_ENV === 'develement';

const config = {
    ....
}

if(isDev){
    //webpack-dev-server不能使用chunkhash,否则会报错
    config.output.filename ='[name]-[hash].js';
    config.devtool = '#cheap-module-eval-source-map';

    config.plugins.push(
        new webpack.HotModuleReplacementPlugin(), //热更新插件
        new webpack.NoEmitOnErrorsPlugin() //防止错误信息导致webpack退出
    )

    //启动开发服务器
    config.devServer={
        contentBase:path.join(__dirname,'dist'),
        compress:true, //启用gzip压缩
        port:8080,
        hot:true, //启用webpack热模块替换特性
        open:true //是否在开始服务器后打开浏览器
    }
}

在devServer中配置hot:true并不在代表已经启用了热模块替换,还需要使用webpack.HotModuleReplacementPlugin插件才能生效,hot仅仅是一个开关

单独打包css文件

想vue文件中的样式通常会被打包进js文件中,在该组件被加载时同时加载样式。而有一些公共的样式通常会写在单独的文件中,如果我们在多个组件中引用公共样式,那么公共样式会在多个js模块中被打包,这样会增加文件的体积。这是应该将这些公共样式提取出来单独打包。

这里我们使用extract-text-webpack-plugin插件来提取公共样式,所以此时我们的配置文件中就该改为这样:

var ExtracTextPlugin = require('extract-text-webpack-plugin');

const config ={
    module:{
        rules:[
            {
                test: /\.scss/,
                use: ExtracTextPlugin.extract({
                    use: [{
                        loader: 'css-loader'
                    }, {
                        loader: 'sass-loader'
                    }]
                })
            }
        ]
    },
    plugins:[
         new ExtracTextPlugin('style-[contentHash:8].css')
    ]
}

这样就能将scss文件单独打包了

提取公共模块

同理我们在项目中使用类库,也需要单独打包,以防止重复加载,节省流量。

这里使用的是webpack自带的插件CommonsChunkPlugin,在entry中添加vendor模块,然后在插件中配置单独打包vue。

var config = {
    entry: {
        app:path.join(__dirname, 'src/main.js'), 
        vendor:['vue']
    },
    plugins:[
        new webpack.optimize.CommonsChunkPlugin({
            name:'vendor'
        })
    ]
}
相关标签: webpack