美文网首页前端之美-VueJswebapck 4.x
webpack 模块化区分开发和生产(14)

webpack 模块化区分开发和生产(14)

作者: 瓦力博客 | 来源:发表于2019-06-12 10:43 被阅读8次

获取全套webpack 4.x教程,请访问瓦力博客

我们正常开发项目会有两种模式,一种是开发模式,另一种是生产模式。在开发模式中,为了便于代码调试方便我们快速定位错误,不会压缩混淆源代码。但在生成模式中,就不需要调试代码,而是需要更快的页面加载,缓存优化等来提高用户体验。因此开发环境和生产环境需要单独配置。

1.开发和生产区别

\|开发模式|生产模式|
-|-|-|
css|处理css文件
添加厂商前缀
提取css
|处理css文件
添加厂商前缀
提取css文件
压缩css
去除注释|
less|处理less文件
添加厂商前缀
提取css|处理less文件
添加厂商前缀
提取css
压缩css
去除注释|
sass|处理sass文件
添加厂商前缀
提取css|处理sass文件
添加厂商前缀
提取css
压缩css
去除注释|
图片|去缓存
压缩|去缓存
压缩|
字体|去缓存|去缓存|
html|去空格|去空格
压缩
去注释
|
js|es6转es5
懒加载
js语法检测|去注释
压缩
混淆
e6转e5
懒加载
js语法检测|
devServer|需要|不需要|
清除dist|清除dist目录|清除dist目录|

2.文件结构

webpack官方建议开发模式和生产模式的配置分开,然后将两者的公共配置提取出来。这种方法好处就是直接用文件区分环境,如webpack.dev.js就是开发环境,webpack.prod.js就是生产环境。小菜决定不使用官方推荐的模式,而是采用自己习惯的配置模式。

myProject
+|-build
+   |-base
+       |-path.js
+       |-config.js
+   |-mode.js
+   |-entry.js
+   |-devtool.js
+   |-module.js
+   |-plugins.js
+   |-devServer.js
+   |-optimization.js
+   |-output.js
 |-dist
 |-node_modules
 |-src
     |-util
        |-math.js
     |-assets
        |-css
            |-index.css
        |-less
            |-index.less     
        |-sass
            |-index.scss
        |-images
            |-wali_logo.png
     |-index.html
     |-index.js
 |-package.json
 |-webpack.config.js
 |-postcss.config.js
 |-.babelrc

3.模块化

在模块化之前,小菜先更新clean-webpack-plugin插件,最新版本时3.0.0,更新完成后去package.json看下版本是不是最新的。

yarn add clean-webpack-plugin

更新完成后,请按官方文档说明修改之前webpack.config.js的写法

+  const { CleanWebpackPlugin } = require('clean-webpack-plugin');  //清除
+  new CleanWebpackPlugin()

4.package.json

{
  "name": "webpack",
  "version": "1.0.0",
  "description": "webpack测试",
  "sideEffects":[
    "*.css"
  ],
  "main": "index.js",
  "author": "wali",
  "private": true,
  "license": "MIT",
  "scripts": {
   "dev": "npx webpack-dev-server --colors --mode=development",
    "prod": "npx webpack --colors --mode=production",
    "build": "npx webpack --colors --mode=development",
    "analyse": "npx webpack --profile --json> stats.json --colors  --mode=development"
  },
  "dependencies": {
    "@babel/core": "^7.4.5",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/plugin-transform-runtime": "^7.4.4",
    "@babel/polyfill": "^7.4.4",
    "@babel/preset-env": "^7.4.5",
    "@babel/runtime": "^7.4.5",
    "@babel/runtime-corejs2": "^7.4.5",
    "autoprefixer": "^9.5.1",
    "babel-loader": "^8.0.6",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^2.1.1",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^3.0.1",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "image-webpack-loader": "^4.6.0",
    "json5-loader": "^2.0.0",
    "less": "^3.9.0",
    "less-loader": "^5.0.0",
    "loadsh": "^0.0.4",
    "lodash": "^4.17.11",
    "node-sass": "^4.12.0",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "webpack": "^4.32.0",
    "webpack-cli": "^3.3.2",
    "webpack-dev-server": "^3.4.1"
  },
  "devDependencies": {
    "webpack-bundle-analyzer": "^3.3.2"
  }
}

5.path.js

路径build/base/path.js

const path = require('path');   

let dirPath = {};
dirPath.rootDir = path.resolve(__dirname, '../../');   //根路径
dirPath.nodeModule = path.resolve(dirPath.rootDir, './node_modules');  //包路径
dirPath.src = path.resolve(dirPath.rootDir,'./src');   //源文件
dirPath.dist = path.resolve(dirPath.rootDir,'./dist'); //生成线上

dirPath.assets = 'assets';               //静态资源
dirPath.css = 'assets/css';              //css
dirPath.sass = 'assets/sass'             //sass
dirPath.less = 'assets/less';            //less
dirPath.images = 'assets/images';        //images
dirPath.iconfont = 'assets/iconfont';    //iconfont


//将srcPath 挂载出去
module.exports = dirPath;

6.config.js

路径build/base/config.js

读取cli中参数--mode=development来判断当前是开发环境还是生产环境,config一些基础配置

/****
*** config配置
****/
let _mode = process.argv[process.argv.length - 1];
let env = _mode.replace(/--mode=(.+)/g,"$1");

let config = {
    NODE_ENV: env == 'development'?'development':'production',  //development 开发 production 线上
    publicPath: env == 'development'?'/':'http://www.waliblog.com',
    apiUrl:'http://www.waliblog.com',
    port: 9999
}

module.exports = config;

7.mode.js

路径build/mode.js

设置webpack是生成模式还是开发模式

const config = require('./base/config');

let mode = config.NODE_ENV == 'development'?'development':'production';

module.exports = mode;

8.devServer.js

路径build/devServer.js

const dirPath = require('./base/path');
const config = require('./base/config');

let devServer = {
    contentBase: dirPath.dist,
    clientLogLevel: 'info',
    open:true,  //启动时默认打开浏览器
    host:'localhost', //域名 0.0.0.0局域网可访问
    port:config.port || '9999',
    inline:true, //实时更新
    hot:true,    //热替换
    hotOnly:false, //true禁止浏览器自动刷新,false浏览器刷新
    proxy:{
        '/':{
            target: config.apiUrl
        },
        '/upload':{
            target: config.apiUrl
        }
    }
}

module.exports = devServer

9.entry.js

路径build/entry.js

const dirPath = require('./base/path');

let entry = {
    main: dirPath.src + '/index.js'
}

module.exports = entry;

10.devtool.js

路径build/devtool.js

const config = require('./base/config');

const devtool = config.NODE_ENV === 'development'?'cheap-eval-source-map':'cheap-source-map';

module.exports = devtool;

11.module.js

路径build/module.js

const dirPath = require('./base/path');
const config = require('./base/config');

let _module = {
    rules:[
        {
            test:/\.css$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:1
                    }                   
                },
                'postcss-loader'
                
            ]
        },
        {
            test:/\.scss$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'sass-loader',
                'postcss-loader'
            ]
        },
        {
            test: /\.less$/,
            use: [
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'less-loader',
                'postcss-loader'
            ]
        },
        {
            test:/\.(png|svg|jpeg|jpg|gif)$/,
            use:[       
                {
                    loader:'file-loader',
                    options:{
                        name:'[name][sha512:hash:base64:7].[ext]',  //[path] 上下文环境路径
                        outputPath: dirPath.images,  //输出路径 
                        publicPath: config.NODE_ENV === 'development'?dirPath.images:dirPath.images   //公共路径                                                    
                    }
                },
                {
                    loader: 'image-webpack-loader',
                    options: {
                        bypassOnDebug: true, // webpack@1.x
                        disable: true,       // webpack@2.x and newer
                    },
                },
            ]
        },
        {
            test: /\.html$/,
            use:[
                {
                    loader:'html-loader',
                    options:{
                        arrts:['img:src','img:data-src'],
                        minimize: config.NODE_ENV === 'development'? false:true  //是否压缩html
                    }
                }
            ]
        },
        {
            test: /(iconfont.svg)|\.(woff|woff2|eot|ttf|otf)$/,
            use:[
                {
                    loader:'file-loader',
                    options:{
                        name:'[name].[ext]',  //[path] 上下文环境路径
                        outputPath: dirPath.iconfont,  //输出路径       
                        publicPath: config.NODE_ENV === 'development'? dirPath.iconfont: dirPath.iconfont,    //公共路径                            
                    }
                }               
            ]
        },
        {
            test: /\.js$/,
            exclude: /(node_modules|bower_components|lib)/,
            loader: 'babel-loader'
        }
    ]
}

module.exports = _module;

12.pligins.js

路径build/pligins.js

const dirpath = require('./base/path');

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');    //生成html文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');  //清除


let plugins = [
    new HtmlWebpackPlugin({
            title: '瓦力博客',
            template: dirpath.src + '/index.html'   //以src/index.html为编译模板
    }),
    new CleanWebpackPlugin(),
    new webpack.HotModuleReplacementPlugin()
]

module.exports = plugins;

13.optimization.js

路径build/optimization.js

let optimization = {
    usedExports: true,
    splitChunks: {
        chunks: 'all',
        minSize: 30000,
        maxSize: 0,
        minChunks: 1,
        maxAsyncRequests: 5,
        maxInitialRequests: 3,
        automaticNameDelimiter: '~',
        name: true,
        cacheGroups: {
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10
            },
            default: {
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true
            }
        }
    }
}

module.exports = optimization

14.output.js

路径build/output.js

const srcPath = require('./base/path');
const config = require('./base/config');

let output = {
    path: srcPath.dist,
    filename: '[name].[hash].js',
    publicPath: config.publicPath
}

module.exports = output;

15.webpack.config.js

const _mode = require('./build/mode');
const _devtool = require('./build/devtool');
const _entry = require('./build/entry');
const _module = require('./build/module');
const _plugins = require('./build/plugins');
const _devServer = require('./build/devServer');
const _optimization = require('./build/optimization');
const _output = require('./build/output');



module.exports = {
    mode: _mode,
    devtool: _devtool,
    entry: _entry,  
    module: _module,
    plugins: _plugins,
    devServer: _devServer,
    optimization: _optimization,
    output: _output 
}

将webpack配置拆分成单个js文件,然后在组装在一起,通过cli参数来区分是开发模式还是生产模式。拆分好后,在package.json文件中找到scripts运行对应的命令,如果能够运行成功,说明我们目前拆分的没有问题。如果报错了,请认真检查报错原因。

相关文章

网友评论

    本文标题:webpack 模块化区分开发和生产(14)

    本文链接:https://www.haomeiwen.com/subject/azskfctx.html