webpack配置

176 阅读4分钟
webpack是基于commentjs规范 导出使用 module.exports = {} 导入时使用require

es6导出时使用 export.default xxx = {} 或者export xx ={} 导入时使用import

commentjs语法比es6语法高级 浏览器不认识require 所以需要使用webpack

webpack的核心概念

Entry: 入口
Module:模块,webpack中一切皆是模块
Chunk:代码库,一个chunk由十多个模块组合而成,用于代码合并与分割
Loader:模块转换器,用于把模块原内容按照需求转换成新内容
Plugin:扩展插件,在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要做的事情
Output: 输出结果

安装

npm i webpack webpack-cli --save-dev

简单的配置

新建一个webpack.config.js 在这个文件中进行配置 配置的话 需要导出

const path = require('path')
module.exports = {
    entry:path.resolve(_dirname,'./src/index'),  //打包的入口(把什么进行打包)
    output:{ //打包的出口
        path:path.resolve(_dirname,'dist'),  //打包到哪里
        filename:bundle.js  //打包后的名字
    }
    
}

使用npx webpack 会把index.js进行打包 打包到dist文件夹下面的bundle.js 默认是打包到生产环境 可以使用 npx webpack --mode development(开发环境) 或者 npx webpack --mode production(生产环境) 进行指定打包的环境 打包到开发环境的代码没有压缩 打包到生产环境的代码进行压缩(显示在一行)

每一次都需要写好长的指令进行打包 这样不方便 所以可以在package.json中进行设置脚本(script)

"scripts": {
    "dev": "webpack --mode development --env.development",
    "build": "webpack --mode production --env.production"
},

这样就可以直接使用npm run dev=>打包到开发环境 或者npm run build=>打包到生产环境

module.exports = (env)=>{
    console.log(env) //{production:true} {development:true}
}

当npm run dev 或者 npm run build 时 会把env传送过来

正式的配置

package.json

"scripts": {
    "dev:build": "webpack --env.development  --config ./build/webpack.base.js",
    "dev": "webpack-dev-server --env.development --config ./build/webpack.base.js",
    "build": "webpack --env.production  --config ./build/webpack.base.js"
  },

当npm run dev 时会把项目打包到内存中 在项目的目录下不可以看到

当npm run build 时会把项目打包到dist文件夹下 在项目的目录下可以看到 代码压缩

当npm run dev 时会把项目打包到dist文件夹下 在项目的目录下可以看到 代码没有压缩

安装

npm i webpack-dev-server --save-dev

作用 当npm run dev 时会把项目打包到内存中 像vue脚手架npm run server 一样 会启动一个服务器 localhost:8080

--config是在npm run xx 时告诉应该去./build/webpack.base.js执行 如果不写的话还是去找webpack.config.js执行

新建3个配置文件

webpack.base.js(生产环境和开发环境共同的操作)

webpack.dev.js(开发环境的操作)

webpack.prod.js(生产环境的操作)

在webpack.base.js中

//引入开发环境和生产环境的操作
const dev = require('./webpack.dev')
const prod = require('./webpack.prod')

const path = require('path')
//实现合并
const merge = require('webpack-merge')
//把.html模板打包到dist
const htmlWebpackPlugin = require('html-webpack-plugin')
//清除没有用到的.js文件
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
//把css打包到外部
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = (env)=>{
    // console.log('base...')
    let isDev = env.development
    // console.log(isDev)
    //base是开发模式和生产模式共同的
    const base = {
        entry:path.resolve(__dirname,'../src/index'),
        module:{
            rules:[
                //style-loader是把css打包到内部 形成style标签 然后嵌入到.html中
                {
                    test:/\.css$/,
                    use:[
                        // 'style-loader',
                        isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
                        {
                            loader:'css-loader',
                            options:{
                                importLoaders:2
                            }
                        },
                        //让css识别@import './a.scss'
                        'sass-loader',
                        //实现旋转
                        "postcss-loader"
                    ]
                },
                {test:/\.scss$/,use:['style-loader','css-loader','sass-loader']},
                {
                    // 处理图片
                    test:/\.(png|jpg|jpeg|gif)$/,
                    use:{
                        loader:"url-loader",
                        options:{
                            name:"image/[name].[hash:7].[ext]",
                            limit:1024*10,  // 1024*10 10以下,会转成base64一大堆字符串
                            outputPath: 'images'
                        }
                    }
                    // use:"file-loader"  // file-loader默认的功能是copy的功能  如果一个图片比较小  把这个图片转化成base64  本质就是把一张图片转成字符串 好处就是避免二次请求  一般会把一些小图标转成base64
                }
            ]
        },
        output:{
            filename:'bundle.js',
            path:path.resolve(__dirname,'../dist')
        },
        plugins:[
            new CleanWebpackPlugin(), //会把在dist中没有用到的文件删除
            //把.html打包到dist上 成功后这个.html会自动引入.js  .css 
            // css打包到dist 那么在.html中使用link进行自动引入
            new htmlWebpackPlugin({
                template:path.resolve(__dirname,'../public/index.html'),
                filename:'index.html', //打包到dist中的.html的名字 如果不设置默认同public下面的名字一样
                minify:!isDev && {
                    //生产模式 因为开发模式在浏览器中不会看里面的代码 只会看展示的效果
                    removeAttributeQuotes:true, //会把打包到dist下的.html里面的引号去掉 
                    collapseWhitespace:true //会把打包到dist下的.html所有内容放到一行
                }              
            }),
            //把css打包到css文件夹下面的main.css 
            !isDev && new MiniCssExtractPlugin({
                    filename:'css/main.css'
            })
        ].filter(Boolean)
    }
    // return base //不写下面代码时  需要把base返回 不返回的话 还是默认的设置 
    // 例如生成文件的名字不是自己设置的bundle.js 而是默认的main.js
    if(isDev){
        // merge是把两配置文件合并  需要返回  如果不返回走的还是默认的配置文件
        //是开发环境
        return merge(base,dev)
        
    }else{
        //是生产环境
        return merge(base,prod)
    }
}

webpack-merge

安装引入

npm i webpack-merge --save-dev
const merge = require('webpack-merge')

作用

是实现模块的合并 

用法

merge(base,dev)  merge(base,prod)

html-webpack-plugin

安装引入

npm i html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin')

作用

把.html文件打包到dist文件夹下

用法

new htmlWebpackPlugin({
    template:path.resolve(__dirname,'../public/index.html'),
    filename:'index.html', //打包到dist中的.html的名字 如果不设置默认同public下面的名字一样
    minify:!isDev && {
        //生产模式 因为开发模式在浏览器中不会看里面的代码 只会看展示的效果
        removeAttributeQuotes:true, //会把打包到dist下的.html里面的引号去掉 
        collapseWhitespace:true //会把打包到dist下的.html所有内容放到一行
    }              
}),

clean-webpack-plugin

安装引入

npm i clean-webpack-plugin
const CleanWebpackPlugin = require('clean-webpack-plugin')

作用

把dist文件夹下面没有用到的删除

用法

new CleanWebpackPlugin()

css-loader style-loader

如果在index.js中引入css 那么在打包index.js时会出错 需要使用正确的loader

安装

npm i css-loader style-oader --save-dev

作用

处理css 

用法

{
    test:/\.css$/,
    use:['style-loader','css-loader'] 
    //数组是从右向左 
    //先识别css文件 然后把css打包到内部 使其变成标签 嵌入到.html
    
},

node-sass sass-loader

安装

npm i node-sass sass-loader --save-dev

作用

处理scss文件

用法

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

如果是在index.js中引入.scss文件中 不用做一下的配置

当在index.css 中引入.scss文时件 使用@import './a.scss' css不认识import 所以需要对css进行配置

{
    test:/\.css$/,
    use:[
        'style-loader',
        {
            loader:'css-loader',
            options:{
                importLoaders:1
            }
        },
        //让css识别@import './a.scss'
        'sass-loader',
        
    ]
},

mini-css-extract-plugin

安装引入

npm i mini-css-extract-plugin --save-dev
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

作用

把.css文件引入到dist文件夹下 上面的处理css只是把.css进行解析 嵌入到.html中
并没有在dist文件夹下面生成.css文件

用法

第一步

//把css打包到css文件夹下面的main.css 
!isDev && new MiniCssExtractPlugin({
        filename:'css/main.css' //打包成功后会显示在dist/css/main.css
})

第二步

{
    test:/\.css$/,
    use:[
        // 'style-loader',
        isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
        //如果是开发环境就直接嵌入到.html 如果是生产环境则需要打包到dist/css/main.css
        {
            loader:'css-loader',
            options:{
                importLoaders:2
            }
        },
        //让css识别@import './a.scss'
        'sass-loader',
    ]
},

file-loader

安装

npm i file-loader --save-dev

作用

处理图片 

在index.js中

import logo from './image/logo.jepg'
let image = document.createElement('image')
image.src = logo
document.body.appendChild(image)

这样在打包index.js时会出错 需要正确的loader

用法

{
    // 处理图片
    test:/\.(png|jpg|jpeg|gif)$/,
    use:"file-loader"  // file-loader默认的功能是copy的功能 
    //如果一个图片比较小  把这个图片转化成base64  本质就是把一张图片转成字符串 
    //好处就是避免二次请求  一般会把一些小图标转成base64
}

url-loader

安装

npm i url-loader --save-dev

作用

处理图片和上面的区别就是上面的那种

用法

{
    // 处理图片
    test:/\.(png|jpg|jpeg|gif)$/,
    use:{
        loader:"url-loader",
        options:{
            name:"[name].[hash:7].[ext]",
            limit:1024*10,  // 1024*10 10以下,会转成base64一大堆字符串
            outputPath: 'images' //打包到dist下面的images文件夹下
        }
    }
    
}

postcss-loader

autoprefixer

在webpack.dev.js中

可以对服务器进行配置

const path = require('path')
module.exports = {
    mode:'development',
    devServer:{
        // 只有npm run dev时看到有没有改变
        //配置开发环境服务器
        port:3000, //不设置 默认为8080 
        contentBase: path.resolve(__dirname,'../dist'),
        compress:true
    }
}