一文帮你了解webpack搭建过程[从零构建webpack(Vue,React)版本:v4.42.0]

268 阅读8分钟

文件传送门:github.com/wgzero/webp…

I.webpack的搭建过程

1.初始化一个文件demo,npm init -y

2.安装npm i webpack webpack-cli -D 

3.同时在demo下面创建一个public目录,public下面创建一个index.html页面

<!DOCTYPE html>
    <html lang="en">
        <head>    
            <meta charset="UTF-8">    
            <meta name="viewport" content="width=device-width, initial-scale=1.0">    
            <meta http-equiv="X-UA-Compatible" content="ie=edge">    
            <title>webpack</title>
        </head>
        <body>    
            <div id="root"></div>
        </body>
</html>

4.在demo下面创建一个src目录,在src目录下创建index.js文件

// index.js
var app =  document.getElementById('root')
app.innerHTML = 'hello world'

5.在demo目录下创建一个webpack.config.js文件

const path = require('path')module.exports = {
    mode: 'development',    
    entry: './src/index.js',    
    output: {        
        filename: '[name].js',        
        path: path.resolve(__dirname, './dist')    
    }
}

6.安装:html-webpack-plugin clean-webpack-plugin webpack-dev-server

 npm i html-webpack-plugin clean-webpack-plugin webpack-dev-server -D
// html-webpack-plugin: 打包生出一个html页面
// clean-webpack-plugin: 清除打包生成的文件
// webpack-dev-server: 开启热服务更新

7.在webpack.config.js文件下添加内容

const path = require('path')
//  打包生成html页面
const htmlWebpackPlugin = require('html-webpack-plugin')
// 清除打包生成的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// webpack热模块更新要和webpack-dev-server配合使用
const webpack = require('webpack')

module.exports = {    
    // 模式    
    // mode: 'development',    
    mode: 'production',    
    devServer: {        
        contentBase: './public',        
        open: true,        
        port: 8081,        
        hot: true    
    },    
    // 入口    
    entry: './src/index.js',    
    // module    
    // 插件是一个数组形式    
    plugins: [        
        new htmlWebpackPlugin({template: 'public/index.html'}),        
        new CleanWebpackPlugin(),        
        new webpack.HotModuleReplacementPlugin()    
    ],    
    // 出口    
    output: {        
        filename: '[name].js',        
        path: path.resolve(__dirname, './dist')    
    }
}

8.配置一下package.json文件

"dev": "webpack-dev-server",  // 开启热更新
"build": "npx webpack", // 打包生成dist文件夹

9.tips:mode为development模式是没有开启压缩的,mode为production模式是开启了压缩模式的。

10.文件传送门:github.com/wgzero/webp…

II.webpack搭建开发环境和线上环境

1.通过创建的demo改造一下,创建build目录,在build目录下创建三个文件webpack.common.js、webpack.dev.js、webpack.prod.js文件

2.webpack.common.js是公共配置文件,webpack.dev.js是开发环境,webpack.prod.js是生产环境

3.安装autoprefixer浏览器前缀

npm i autoprefixer postcss postcss-loader -D

在demo目录下创建postcss.config.js文件

module.exports = {    
    plugins: [        
        require('autoprefixer')    
    ]
}

3.安装ES6,7转成ES5语法

npm i @babel/core @babel/plugin-transform-runtime @babel/polyfill -D
npm i @babel/preset-env @babel/runtime @babel/runtime-corejs2

在demo目录下创建.babelrc文件

{
     "presets": [["@babel/preset-env",{
        "targets": {
            "chrome": "67"
        },
        "corejs": "2",
        "useBuiltIns": "usage"
      }]
    ]
}

4.安装sass和less

npm css-loader style-loader less less-loader sass sass-loader file-loader -D

在webpack.config.js文件下配置

module: {        
    rules: [
             // 图片            
            {                
                test: /\.(png|jpg|gif)$/,                
                use: [                    
                        {                        
                            loader: 'file-loader',                        
                            options: {                            
                            // 文件输出名字                            
                            name: '[name].[ext]',                            
                            // 文件输出路径                            
                            outputPath: 'images/',                            
                            // 文件输入大小                            
                            limit: 20480                        
                            }                    
                         }                
                    ]            
            },
            {               
              // 引入css模块打包编译:  style-loader 和 css-loader               
                 test: /\.less$/,                
                  // 执行顺序:从下到上,从右到左               
                 use: [                    
                        'style-loader',                    
                        'css-loader',                    
                        'less-loader',                    
                        'postcss-loader'                
                    ]            
            },           
             {                
            // 引入css模块打包编译:  style-loader 和 css-loader                
                test: /\.scss$/,                
                    // 执行顺序:从下到上,从右到左               
                 use: [                    
                    'style-loader',                        
                        {                       
                         // 这里表示从下往上执行过程中,无论sass加载多少个内嵌scss文件,都要执行下面两个                       
                           loader: 'css-loader',                       
                           options: {                            
                                        importLoaders: 2,                            
                                        // 开启css模块化                            
                                        modules: true                        
                                    }                    
                        },                    
                    'sass-loader',                    
                    'postcss-loader'                
                    ]            
                }, 
                     {                
                        // 引入css模块打包编译:  style-loader 和 css-loader                
                        test: /\.css$/,                
                        // 执行顺序:从下到上,从右到左                
                        use: [                    
                                'style-loader',                    
                                'css-loader',                    
                                'postcss-loader'                
                            ]            
                    },        
        ]    
    },

5.安装webpack-merge代码合并

npm i webpack-merge -D

把webpack.config.js文件内容复制到webpack.common.js文件中,并将文件加以改造

// webpack.common.js文件
const path = require('path')
//  打包生成html页面
const htmlWebpackPlugin = require('html-webpack-plugin')
// 清除打包生成的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = {    
    // 模式    
    mode: 'development',    
    // 入口    
    entry: './src/index.js',    
    // module    
    module: {        
        rules: [            
                    // 图片            
                    {                
                        test: /\.(png|jpg|gif)$/,                
                        use: [                    
                                {                        
                                    loader: 'file-loader',                        
                                    options: {                            
                                    // 文件输出名字                            
                                    name: '[name].[ext]',                            
                                    // 文件输出路径                            
                                    outputPath: 'images/',                            
                                    // 文件输入大小                            
                                    limit: 20480                        
                                    }                    
                                }                
                            ]           
                     },            
                    {                
                        // 引入css模块打包编译:  style-loader 和 css-loader                
                        test: /\.less$/,                
                        // 执行顺序:从下到上,从右到左                
                        use: [                    
                                'style-loader',                   
                                'css-loader',                    
                                'less-loader',                    
                                'postcss-loader'                
                            ]            
                    },            
                    {                
                        // 引入css模块打包编译:  style-loader 和 css-loader                
                        test: /\.scss$/,                
                        // 执行顺序:从下到上,从右到左                
                        use: [                    
                                'style-loader',                   
                                 {                        
                                // 这里表示从下往上执行过程中,无论sass加载多少个内嵌scss文件,都要执行下面两个
                                        loader: 'css-loader',                        
                                        options: {                           
                                             importLoaders: 2,                            
                                             // 开启css模块化                            
                                             modules: true                        
                                            }                    
                                    },                    
                                'sass-loader',                    
                                'postcss-loader'                
                            ]            
                    },
                     {                
                        // 引入css模块打包编译:  style-loader 和 css-loader                
                        test: /\.css$/,                
                        // 执行顺序:从下到上,从右到左                
                        use: [                    
                                'style-loader',                    
                                'css-loader',                    
                                'postcss-loader'                
                            ]            
                    },        
                ]    
        },    

        // 插件是一个数组形式    
        plugins: [        
                new htmlWebpackPlugin({ template: 'public/index.html' }),        
                new CleanWebpackPlugin()    
    ],    

    // 出口    
    output: {        
            filename: '[name].js',        
            path: path.resolve(__dirname, './dist')    
    }
}

// webpack.dev.js文件 开启热更新
const webpack = require('webpack')
// 引入webpack.common.js文件
const common = require('./webpack.common')
// 引入合并const merge = require('webpack-merge')
const devConfig = {
    // 生产模式    
    mode: 'development',    
    devServer: {        
        contentBase: './public',        
        open: true,        
        port: 8081,        
        hot: true    
    },    
    plugins: [        new webpack.HotModuleReplacementPlugin()    ],    
    // 开启树摇    tree shaking
    optimization: {        
        usedExports: true    
    }
}

module.exports = merge(common, devConfig)

// webpack.prod.js文件
const merge = require('webpack-merge')
// 
// 引入webpack.common.js文件
const common = require('./webpack.common')
const prodConfig = {
    //  线上模式    
    mode: 'production',    
    devtool:  'cheap-module-source-map'
}

module.exports = merge(common, prodConfig)

6.接下来将代码拆分生成js文件、css文件、images文件

npm i extract-text-webpack-plugin@next -D //css代码拆分

// webpack.common.js文件改造
const path = require('path')
//  打包生成html页面
const htmlWebpackPlugin = require('html-webpack-plugin')
// 清除打包生成的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// 提取css样式
const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {    
        // 模式    
        mode: 'development',    
        // mode: 'production',   
         // 入口    
        entry: './src/index.js',    
        // module   
        module: {        
            rules: [            
                    // 图片           
                        {                
                            test: /\.(png|jpg|gif)$/,                
                            use: [                    
                                    {                        
                                        loader: 'file-loader',                        
                                        options: {                           
                                                 // 文件输出名字                            
                                                name: '[name].[ext]',     
                                                   // 文件输出路径     
                                                outputPath: 'images/',     
                                               // 文件输入大小                            
                                                limit: 20480                        
                                                }                  
                                    }                
                                ]            
                        },            
                            {                
                                // 引入css模块打包编译:  style-loader 和 css-loader    
                                test: /\.less$/,                
                                // 执行顺序:从下到上,从右到左                 
                                use: ExtractTextPlugin.extract({                    
                                        use: [{                        
                                                loader: "css-loader"                    
                                                }, {                        
                                                loader: "less-loader"                   
                                                }, {                        
                                                loader: "postcss-loader"                    
                                                }],                    
                                // use style-loader in development                    
                                fallback: "style-loader"                
                                })            
                            },            
                            {                
                                // 引入css模块打包编译:  style-loader 和 css-loader     
                               test: /\.scss$/,                
                                use: ExtractTextPlugin.extract({                    
                                        use: [{                       
                                             loader: "css-loader"                    
                                                }, {                       
                                             loader: "sass-loader"                   
                                                 }, {                       
                                             loader: "postcss-loader"                   
                                             }],                   
                                 // 在开发环境使用 style-loader                    
                                fallback: "style-loader"                
                                })            
                            }, 
                            {                
                                // 引入css模块打包编译:  style-loader 和 css-loader        
                                test: /\.css$/,                
                                // 执行顺序:从下到上,从右到左                
                                use: ExtractTextPlugin.extract({                    
                                fallback: "style-loader",                    
                                use: [                        
                                        'style-loader',                        
                                        'css-loader',                        
                                        'postcss-loader'                    
                                    ]                
                                })            
                            },        
            ]    
        },    
    
        // 插件是一个数组形式    
            plugins: [        
                    new htmlWebpackPlugin({ template: 'public/index.html' }),
                    // 生成css文件目录        
                    new ExtractTextPlugin({            filename: 'css/[name].css'        }),
                    new CleanWebpackPlugin()    ],    
        // 出口    
        output: {
                    //  生成js文件目录        
                    filename: 'js/[name].js',        
                    path: path.resolve(__dirname, '../dist')    
            }
}

7.将package.json文件配置一下

"scripts": {    
    "dev": "webpack-dev-server --config ./build/webpack.dev.js",    
    "prod": "webpack --config ./build/webpack.prod.js" 
 },

npm run dev // 是生产模式
npm run prod // 是线上模式

8.文件传送门:github.com/wgzero/webp…

III.Vue从零搭建webpack

1.创建demo,npm init -y生成package.json文件

2.在demo下创建src,public目录,src目录下创建assets、components、router、store、views目录,在src目录下创建App.vue文件和main.js文件,在public目录下面创建index.html页面


<!DOCTYPE html>
    <html lang="en">
        <head>    
            <meta charset="UTF-8">    
            <meta name="viewport" content="width=device-width, initial-scale=1.0">    
            <meta http-equiv="X-UA-Compatible" content="ie=edge">    
            <title>Vue&&Webpack</title>
        </head>
    <body>    
            <div id="root"></div>
    </body>
</html>

3.安装webpack webpack-cli webpack-dev-server html-webpack-plugin clean-webpack-plugin

npm i webpack webpack-cli webpack-dev-server html-webpack-plugin clean-webpack-plugin -D

// 配置webpack.config.js
const path = require('path')
//打包生成html页面
const htmlWebpackPlugin = require('html-webpack-plugin')
// 清除dist目录下的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// webpack开启热更新const webpack = require('webpack')

module.exports = {    
        // 模式    
        mode: 'development',    
        // 热更新    
        devServer: {        
                contentBase: './public',        
                open: true,        
                port: 8080,        
                hot: true    
        },    

        // 入口 demo/src/main.js    
        entry: './src/main.js',    
        module: {},    
        plugins: [        
                    new htmlWebpackPlugin({ template: './public/index.html' }),        
                    new webpack.HotModuleReplacementPlugin(),        
                    new CleanWebpackPlugin()    
            ],    
        // 出口    
        output: {        
                filename: 'js/[name].[hash].js',        
                // chunkFilename,会在打包后生成一个chunk.js的文件        
                chunkFilename: 'js/[name].[hash].js',        
                path: path.resolve(__dirname, './dist')    
            }
}

4.Vue需要的环境

npm i vue vuex vue-router core-js -S

//在src目录下创建main.js
import Vue from 'vue'
import router from './router/index'
import store from './store/index'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({    
    router,    
    store,    
    render: h => h(App)
}).$mount("#root")

// 在src目录下创建router目录 在router目录下创建index.js文件
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [    
    {       
        path: '/',        
        name: 'home',        
        component: Home    
    },    
    {        
        path: '/about',        
        name: 'about',        
        component: () => import(/*webpackChunkName: "about" */'../views/About.vue')     
    }
]

const router = new VueRouter({    routes})

export default router;

// 在src目录下创建store目录 在store目录下创建index.js文件
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({    
    state: {},    
    mutations: {},    
    actions: {},    
    modules: {}
})

// 在src目录下创建views目录 在目录下创建Home.vue文件
<template>  
    <div class="home">      
        <h3>home pages</h3>      
        <div class="content">          我是home页面      </div>  
    </div>
</template>

<script>
export default {  
    props: {},  
    components: {},  
    data() {    
            return {    }  
        },
}
</script>

<style lang="less" scoped>

.home{    
    font-size: 25px;    
    .content{        
        color: pink;    
    }
}

</style>

// 在src目录下创建views目录 在目录下创建About.vue文件
<template>  
    <div class="about">      
        <h3>About</h3>      
        <div class="img">        
            <img src="https://avatars1.githubusercontent.com/u/34123694?s=60&v=4" alt=""> 
        </div>  
    </div>
</template>

<script>
export default {  
    props: {},  
    components: {},  
    data() {    
            return {    }  
        },
}
</script>

<style lang="less" scoped>

.about{    
    img{        
        width: 200px;        
        height: 200px;        
        border-radius: 50%;    
    }
}
</style>

以上模板建好之后,还不可以运行

5.Vue编译模板

npm i vue-template-compiler vue-loader -D

// 在webpack.config.js文件下 配置一下vue和vue-loader
// Vue
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module: {        
        rules: [            
                // Vue模块            
                    {               
                         test: /\.vue$/,                
                         loader: 'vue-loader'            
                    }        
                ]    
    },

plugins: [        new VueLoaderPlugin()    ],

6.浏览器css前缀

npm i autoprefixer postcss postcss-loader -D

// 在demo目录下创建postcss.config.js文件
module.exports = {    
    plugins: [        require('autoprefixer')    ]
}

7.css,less,文件解析

npm i css-loader style-loader less less-loader file-loader -D

// 在webpack.config.js文件下 配置一下css less file
  module: {    
            rules: [      
                        // Vue模块     
                         {        
                            test: /\.vue$/,        
                            loader: 'vue-loader'      
                         },      
                        // css模块      
                         {        
                                test: /\.css$/i,        
                                use: ['style-loader', 'css-loader','postcss-loader']      
                            },      
                        // less 模块      
                           {        
                                test: /\.less$/,        
                                use: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader']      
                            },      
                        // 文件配置file      
                            {        
                                test: /\.(png|jpg|gif)$/,        
                                use: [          
                                            {            
                                                loader: 'file-loader',            
                                                options: {              
                                                        // 文件输出名字              
                                                            name: '[name].[ext]',          
                                                        // 文件输出路径              
                                                            output: 'images/',            
                                                          // 文件输入大小              
                                                            limit: 20480           
                                                         }          
                                            }        
                                    ]      
                            }    
        ]  
},

9.ES6,7转成ES5语法

npm i @babel/core @babel/plugin-transform-runtime @babel/polyfill @babel/preset-env -D
npm i @babel/runtime @babel/runtime-corejs2 @vue/cli-plugin-babel babel-loader -D
// 在webpack.config.js文件下 配置一下js
 module: {        
        rules: [            
                    // js            
                    {                
                        test: /\.js$/,                
                        // 好处:babel在做语法解析的时候,会忽略掉node_modules下的第三方模块,让我们打包的速度更快               
                         exclude: /node_modules/,                
                        // 这里用了babel-loader,在主目录下配置了.babelrc的文件          
                          use: ["babel-loader"]            
                    }        
        ]    
},

// 在demo目录下创建.babelrc文件
{    
    "presets": [["@babel/preset-env",{       
        "targets": {           
                        "chrome": "67"       
                    },       
        "corejs": "2",       
        "useBuiltIns": "usage"     
        }],   
    ]
}

10.生成css文件并压缩css代码,【+++】三个连加代表添加部分代码

npm i  extract-text-webpack-plugin@next optimize-css-assets-webpack-plugin -D

const path = require('path')
//打包生成html页面
const htmlWebpackPlugin = require('html-webpack-plugin')
// 清除dist目录下的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// webpack开启热更新
const webpack = require('webpack')
// Vue
const VueLoaderPlugin = require('vue-loader/lib/plugin')
// css代码拆分 +++
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// css代码压缩 +++
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = {    
    // 模式    
    mode: 'development',    
    // 热更新    
    devServer: {        
                    contentBase: './public',       
                     open: true,        
                    port: 8080,        
                    hot: true    
            },    
    // 入口 demo/src/main.js    
    entry: './src/main.js',    
    module: {        
                rules: [            
                            // js            
                            {                
                                test: /\.js$/,                
                                // 好处:babel在做语法解析的时候,会忽略掉node_modules下的第三方模块,让我们打包的速度更快               
                                 exclude: /node_modules/,                
                                // 这里用了babel-loader,在主目录下配置了.babelrc的文件        
                                loader: "babel-loader",            
                                },            
                            // Vue模块            
                            {                
                                test: /\.vue$/,                
                                loader: 'vue-loader'            
                                },            
                                // 图片           
                             {               
                                 test: /\.(png|jpg|gif)$/,                
                                 use: [                    
                                            {                        
                                                loader: 'file-loader',                       
                                                options: {                            
                                                // 文件输出名字                           
                                                name: '[name].[ext]',              
                                                  // 文件输出路径                        
                                                outputPath: 'images/',          
                                                  // 文件输入大小                        
                                                limit: 20480                        
                                                }                   
                                             }                
                                        ]            
                                },            
                                    {                
                                        // 引入css模块打包编译:  style-loader 和 css-loader               
                                         test: /\.less$/,                
                                        // 执行顺序:从下到上,从右到左  +++               
                                         use: ExtractTextPlugin.extract({                    
                                            use: [{                        
                                                loader: "css-loader"                    
                                                }, {                       
                                                 loader: "less-loader"                   
                                                 }, {       
                                             loader: "postcss-loader"                    
                                                }],                
                                         fallback: "style-loader"               
                                         })            
                                    },            
                                    {                
                                            // 引入css模块打包编译:  style-loader 和 css-loader     
                                           test: /\.css$/,               
                                             // 执行顺序:从下到上,从右到左                
                                            use: ['style-loader', 'css-loader', 'postcss-loader']     
      
                                     },            
        ]    
},    

plugins: [        
            new htmlWebpackPlugin({ template: './public/index.html' }),        
            new webpack.HotModuleReplacementPlugin(),
           // +++        
            new ExtractTextPlugin({            
                    filename: 'css/[name].[hash].css'       
                 }),       
             new CleanWebpackPlugin(),        
            new VueLoaderPlugin()    
    ],    

// webpack自带代码拆分功能    
optimization: {        
    // // 开启tree shaking        
     usedExports: true,        
    // 压缩css样式,提高webpack打包速度 +++        
    minimizer: [new OptimizeCSSAssetsPlugin({})],        
 },    

// 出口    
output: {        
    filename: 'js/[name].[hash].js',        
    // chunkFilename,会在打包后生成一个chunk.js的文件       
    chunkFilename: 'js/[name].[hash].js',        
    path: path.resolve(__dirname, './dist')   
   }
}

11.最终webpack.config.js配置文件

const path = require('path')

//打包生成html页面
const htmlWebpackPlugin = require('html-webpack-plugin')
// 清除dist目录下的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// webpack开启热更新
const webpack = require('webpack')
// Vue
const VueLoaderPlugin = require('vue-loader/lib/plugin')

// css代码拆分
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// css代码压缩
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = {    
        // 模式    
        mode: 'development',    
        // 热更新    
        devServer: {        
                contentBase: './public',        
                open: true,        
                port: 8080,        
                hot: true    
        },    
        // 入口 demo/src/main.js    
        entry: './src/main.js',    
        module: {        
                rules: [            
                        // js            
                        {                
                            test: /\.js$/,                
                            // 好处:babel在做语法解析的时候,会忽略掉node_modules下的第三方模块,让我们打包的速度更快     
                            exclude: /node_modules/,                
                            // 这里用了babel-loader,在主目录下配置了.babelrc的文件                
                           loader: "babel-loader",            
                        },            
                        // Vue模块            
                            {                
                                test: /\.vue$/,                
                                loader: 'vue-loader'            
                            },            
                        // 图片            
                            {                
                                test: /\.(png|jpg|gif)$/,               
                                 use: [                    
                                        {                        
                                            loader: 'file-loader',                      
                                            options: {                            
                                                    // 文件输出名字                            
                                                    name: '[name].[ext]',                          
                                                      // 文件输出路径                            
                                                    outputPath: 'images/',                           
                                                     // 文件输入大小                            
                                                    limit: 20480                       
                                                 }                    
                                            }                
                                        ]            
                                },           
                                 {                
                                        // 引入css模块打包编译:  style-loader 和 css-loader         
                                       test: /\.less$/,                
                                        // 执行顺序:从下到上,从右到左     
                                       use: ExtractTextPlugin.extract({                    
                                               use: [{                           
                                                            loader: "css-loader"                    
                                                        }, {                       
                                                             loader: "less-loader"                    
                                                        }, {                        
                                                            loader: "postcss-loader"                    
                                                    }],                    
                                            // use style-loader in development                    
                                            fallback: "style-loader"                
                                        })            
                                },            
                                    {                
                                        // 引入css模块打包编译:  style-loader 和 css-loader               
                                         test: /\.css$/,                
                                        // 执行顺序:从下到上,从右到左                
                                        use: ['style-loader', 'css-loader', 'postcss-loader']            
                                    },        
        ]    
    },    

    plugins: [        
            new htmlWebpackPlugin({ template: './public/index.html' }),        
            new webpack.HotModuleReplacementPlugin(),        
            new ExtractTextPlugin({            
                    filename: 'css/[name].[hash].css'        
                }),        
            new CleanWebpackPlugin(),        
            new VueLoaderPlugin()    
    ],    

// webpack自带代码拆分功能    
optimization: {        
        // // 开启tree shaking        
        usedExports: true,        
        // 压缩css样式,提高webpack打包速度        
        minimizer: [new OptimizeCSSAssetsPlugin({})],        
        // 新webpack4和旧webpack4的文件单独联系    
    },  
  
// 出口    
output: {        
        filename: 'js/[name].[hash].js',        
        // chunkFilename,会在打包后生成一个chunk.js的文件        
        chunkFilename: 'js/[name].[hash].js',        
        path: path.resolve(__dirname, './dist')    
    }
}

12.配置一下package.json文件

"scripts": {    
    "dev": "webpack-dev-server",  // 开发模式    
    "prod": "webpack", // 打包模式  
},

13.文件传送门:github.com/wgzero/webp…

IV.React从零搭建webpack

1.创建demo-react文件夹,npm init -y 创建pageage.json文件

2.安装webpack webpack-cli

npm i webpack webpack-cli -D

3.在demo-react文件下,创建src,public目录,在public目录下面创建index.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>React&&Webpack</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

4.在src目录下创建index.js文件

var root = document.getElementById('root')
root.innerHTML = 'hello world'

5.安装生成html页面,清除页面,热更新

npm i html-webpack-plugin clean-webpack-plugin webpack-dev-server -D

// 在demo-react目录下创建webpack.config.js文件
module.exports = {
    mode: 'development',
    entry: './src/index.js',
    devServer: {
        contentBase: './public',
        open: true,
        port: 3005,
        hot: true,
    },
    module: {},
    optimization: {
        // 开启tree shaking
        usedExports: true,
    },
    plugins: [
        new htmlWebpackPlugin({ template: 'public/index.html' }),
        new CleanWebpackPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ],
    output: {
        filename: '[name].[hash].js',
        path: path.resolve(__dirname, './dist')
    }
}

6.安装react环境

npm i react react-dom -D

7.安装babel将ES6,7语法转成ES5语法

npm i @babel/core @babel/plugin-proposal-class-properties @babel/preset-react core-js -D

npm i @babel/polyfill @babel/runtime @babel/runtime-corejs2 @babel/preset-env babel-loader -D

在demo-react目录下创建.babelrc文件

{
    "presets": [["@babel/preset-env",{
       "targets": {
           "chrome": "67"
       },
       "useBuiltIns": "usage"
     }],
     "@babel/preset-react"
   ]
}

8.安装css样式浏览器前缀

npm i autoprefixer postcss postcss-loader -D

在demo-react目录下创建postcss.config.js文件

module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}

9.安装css样式,less,font,file

npm i style-loader css-loader less less-loader file-loader url-loader -D

配置webpack.config.js文件

const path = require('path')

const htmlWebpackPlugin = require('html-webpack-plugin')

const { CleanWebpackPlugin } = require('clean-webpack-plugin')

const webpack = require('webpack')

module.exports = {
    mode: 'development',
    entry: './src/index.js',
    devServer: {
        contentBase: './public',
        open: true,
        port: 3005,
        hot: true
    },
    module: {
        rules: [
            // js
            {
                // 配置js和jsx文件可以编译执行
                test: /\.(js|jsx)$/,
                // test: /\.js$/,
                // exclude忽略第三块模块node_modules,让打包更快
                exclude: /node_modules/,
                // 引用.babelrc配置文件
                loader: 'babel-loader'
            },
            // less
            {
                // 引入css模块打包编译:  style-loader 和 css-loader
                test: /\.less$/,
                // 执行顺序:从下到上,从右到左
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader',
                    'postcss-loader'
                ]
            },
            // file
            {
                test: /\.(png|jpg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        // placeholder 占位符
                        name: '[name].[ext]',
                        // 图片保存路径
                        outputPath: 'images/',
                        // 设置大小
                        limit: 2048
                    }
                }
            },
            // font
            {
                test: /\.(eot|ttf|svg|woff)$/,
                use: {
                    loader: 'file-loader'
                }
            },
            // css
            {
                // 引入css模块打包编译:  style-loader 和 css-loader
                test: /\.css$/,
                // 执行顺序:从下到上,从右到左
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader'
                ]
            }
        ]
    },
    optimization: {
        usedExports: true,
    },
    plugins: [
        new htmlWebpackPlugin({ template: 'public/index.html' }),
        new CleanWebpackPlugin(),
        new webpack.HotModuleReplacementPlugin(),
    ],
    output: {
        filename: '[name].[hash].js',
        path: path.resolve(__dirname, './dist')
    }
}

10.css代码拆分以及css代码压缩

npm install -D mini-css-extract-plugin optimize-css-assets-webpack-plugin

这里使用mini-css-extract-plugin作为css代码拆分,

tips坑点:使用mini-css-extract-plugin要注意在生产模式下需要将style-loader去掉

webpack.config.js文件配置

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
module.exports = {
    module: {
        rules: [
            // less
            {
                // 引入css模块打包编译:  style-loader 和 css-loader
                test: /\.less$/,
                // 执行顺序:从下到上,从右到左
                // 使用 MiniCssExtractPlugin更新后代码,去掉了'style-loader'
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'less-loader',
                    'postcss-loader'
                ]
                // 之前的代码
                // use: [
                //     MiniCssExtractPlugin.loader,
                //     'style-loader',
                //     'css-loader',
                //     'less-loader',
                //     'postcss-loader'
                // ]
            },
            // file
            {
                test: /\.(png|jpg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        // placeholder 占位符
                        name: '[name].[ext]',
                        // 图片保存路径
                        outputPath: 'images/',
                        // 设置大小
                        limit: 2048
                    }
                }
            },
            // font
            {
                test: /\.(eot|ttf|svg|woff)$/,
                use: {
                    loader: 'file-loader'
                }
            },
            // css
            {
                // 引入css模块打包编译:  style-loader 和 css-loader
                test: /\.css$/,
                // 执行顺序:从下到上,从右到左
                // use: [
                //     MiniCssExtractPlugin.loader,
                //     'style-loader',
                //     'css-loader',
                //     'postcss-loader'
                // ]
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            }
        ]
    },
    optimization: {
        usedExports: true,
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].[hash].css',
            chunkFilename: 'css/[name].[hash].css',
        }),
        new OptimizeCSSAssetsPlugin({})
    ],

11.webpack.config.js文件最终样子

const path = require('path')

const htmlWebpackPlugin = require('html-webpack-plugin')

const { CleanWebpackPlugin } = require('clean-webpack-plugin')

const webpack = require('webpack')

// css代码
// const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = {
    mode: 'development',
    entry: './src/index.js',
    devServer: {
        contentBase: './public',
        open: true,
        port: 3005,
        hot: true,
        proxy: {
            '/react/api': {
                // http://www.dell-lee.com/react/api/header.json
                target: 'http://www.dell-lee.com',
                "changeOrigin": true
            }
        }
    },
    module: {
        rules: [
            // js
            {
                // 配置js和jsx文件可以编译执行
                test: /\.(js|jsx)$/,
                // test: /\.js$/,
                // exclude忽略第三块模块node_modules,让打包更快
                exclude: /node_modules/,
                // 引用.babelrc配置文件
                loader: 'babel-loader'
            },
            // less
            {
                // 引入css模块打包编译:  style-loader 和 css-loader
                test: /\.less$/,
                // 执行顺序:从下到上,从右到左
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'less-loader',
                    'postcss-loader'
                ]
                
                // use: [
                //     MiniCssExtractPlugin.loader,
                //     'style-loader',
                //     'css-loader',
                //     'less-loader',
                //     'postcss-loader'
                // ]
            },
            // file
            {
                test: /\.(png|jpg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        // placeholder 占位符
                        name: '[name].[ext]',
                        // 图片保存路径
                        outputPath: 'images/',
                        // 设置大小
                        limit: 2048
                    }
                }
            },
            // font
            {
                test: /\.(eot|ttf|svg|woff)$/,
                use: {
                    loader: 'file-loader'
                }
            },
            // css
            {
                // 引入css模块打包编译:  style-loader 和 css-loader
                test: /\.css$/,
                // 执行顺序:从下到上,从右到左
                // use: [
                //     MiniCssExtractPlugin.loader,
                //     'style-loader',
                //     'css-loader',
                //     'postcss-loader'
                // ]
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            }
        ]
    },
    optimization: {
        usedExports: true,
    },
    plugins: [
        new htmlWebpackPlugin({ template: 'public/index.html' }),
        new CleanWebpackPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new MiniCssExtractPlugin({
            filename: 'css/[name].[hash].css',
            chunkFilename: 'css/[name].[hash].css',
        }),
        new OptimizeCSSAssetsPlugin({})
    ],
    output: {
        filename: 'js/[name].[hash].js',
        path: path.resolve(__dirname, './dist')
    }
}

12.在src目录下创建index.js文件

import React, { Component } from 'react'
import ReactDom from 'react-dom'

import axios from 'axios'

import './reset.css'

import zero from './zero.png'

import Child from './child.jsx'


import './index.less'

class App extends Component {

    render(){
        return (
            <div>
                <h1>hello summer 123</h1>
                <Child />
                <img src={ zero } />
            </div>
        )
    }
}

ReactDom.render(<App /> ,document.getElementById('root'))

在src目录下添加child.jsx文件,reset.css文件,index.less文件,zero.png图片

child.jsx

import React, { Component } from 'react'

class Child extends Component {
    render(){
        return (
            <div>hello child</div>
        )
    }
}

export default Child;

reset.css

body,ul,h1,h2,h3,h4,h5,h6,p{    margin: 0;    padding: 0;}

index.less

html{
    background: skyblue;
    color: white;
    body{
        img{
            width: 200px;
            height: 200px;
            border-radius: 50%;
        }
    }
}

13.配置一下package.json文件

"dev": "webpack-dev-server",
"build": "webpack",

14.文件最终样子


15.文件传送门:github.com/wgzero/webp…