• 【One by one系列】一步步学习webpack打包


    Webpack Quick Start

    1.webpack到底是什么?

    前端资源加载/打包工具

    js→js→png→less→sass

    • 静态分析模块的依赖关系
    • 组织合并打包生成对应的静态资源

    2.webpack4新特性

    2.1 mode属性

    • development

      • 浏览器调试工具
      • 注释、开发阶段的详细错误日志和提示
      • 快速和优化的增量构建机制
    • production

      • 开启所有的优化代码
      • 更小的bundle大小
      • 去除掉只在开发阶段运行的代码
      • Scope hoisting(作用域)和Tree-shaking(引入但是没有使用,抖掉)

      webpack --mode development

    2.2 开箱即用webassembly

    2.3 支持多种模块类型

    • javascript/auto
    • javascript/esm
    • javascript/dynamic
    • json
    • webassembly/experimental

    2.4 0CJS

    0配置,webpack4Parcel打包工具启发,尽可能的让开发者运行项目的成本变低。webpack4不再强制需要webpack.config.js作为打包的入口配置文件,默认的入口为./src/和默认的出口./dist,小项目的福音。

    2.5 新的插件系统

    提供了针对插件和钩子的新API。

    • 所有的hook由hooks对象统一管理,它将所有的hook作为可扩展的类属性。
    • 当添加插件时,必须提供一个插件名称
    • 开发插件时,可以选择sync/callback/promise作为插件类型
    • 可以通过this.hooks={myHook:new SyncHook(...)}来注册hook了

    2.6 node.js>=8.9.4

    3.安装

    3.1本地安装

    cnpm install --save-dev webpack

    npm install --save-dev webpack-cli

    3.2全局安装

    npm install --global webpack

    • 不推荐全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。

    4.Quick Start

    4.1新建文件夹

    mkdir webpack-demo

    4.2新建文件

    index.js

    /**
     * es6
     * 写法
     *  
     * */
    import { hello } from './hello_module'
    hello.sayHello()
    
    /**
     * node.js
     * 写法
     */
    // let hello=require('./hello_module')
    // hello.sayHello();
    

    hello_module.js

    /**
     * es6
     */
     export default{
         sayHello:function () {
             console.log("hello")
         }
     }
    
    
    /**
     * nodejs
     */
    module.exports = {
        sayHello: function () {
            console.log("hello")
        }
    }
    

    4.3打包

    . ode_modules.binwebpack --mode development index.js -o output_test_d.js 5kb

    . ode_modules.binwebpack --mode production index.js -o output_test_p.js 2kb

    5.配置文件

    webpack.config.js

    const path=require('path')
    
    module.exports={
        entry:'./input.js', //入口文件
        output:{
            path:path.resolve(__dirname,'dist'),
            filename:'output.bundle.js'
        }
    }
    
    const path=require('path')
    
    module.exports={
        entry:{
            home:'./home.js'
            about:'./about.js'
            other:'./other.js'
        }, //入口文件
        output:{
            path:path.resolve(__dirname,'dist'),
            filename:'[name].bundle.js' //name->home or about or other
        },
        mode:"development"
    }
    

    $:webpack

    6.Loaders

    webpack预处理源文件,例如ts->js

    • Files
    • JSON
    • Transpiling
    • Templating
    • Styling
    • Linting&&Testing
    • Frameworks

    6.1 url-loader

    当文件的大小小于某个指定size时,转成DataURL ,base64,不做雪碧图。

    npm install url-loader --save-dev

    import img from './image.png'

    //webpack.config.js
    module: {
            rules: [{
                test: /.(png|jpg|gif)$/i,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 8192
                    }
                }]
            }]
        }//当文件是png,jpg,gif时,会使用url-loader来进行处理,文件小于8k时,会把文件以DataUrl的形式存储在文件中
    

    6.2 babel-loader

    负责把es6,es7的代码转化为es5的代码

    • 安装

    npm install -D babel-loader @babel/core @babel/preset-env webpack

    moudule:{
        rules:[
            {
                    test: /.js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env']
                        }
                    }
                }
        ]
    }
    

    6.3 sass-loader

    npm install sass-loader node-sass -D

    npm install style-loader css-loader --save-dev

    //webpack.config.js
    module.exports={
        ..
        module:{
        	rules:[{
        		test:/.scss$/,
        		use:[
        			"style-loader",
        			"css-loader",
        			"sass-loader"
        		]
    		}]
    	}
    }
    

    7. Plugins插件

    7.1 MinCssExtractPlugin.loader

    css合并到一起

    • 安装

    npm install mini-css-extract-plugin -D

    const path = require('path')
    const MiniCssExtractPlugin=require("mini-css-extract-plugin");
    const devMode = process.env.NODE_ENV !== 'production';
    
    module.exports = {
        entry: {
            output: './src/index.js'
        }, //入口文件
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: '[name].bundle.js' //name->home or about or other
        },
        // mode: "production",
        mode:"development",
        plugins:[
            new MiniCssExtractPlugin({
                filename:"[name].[hash].css",//name->home
                chunkFilename:"[id].[hash].css"
            })
        ],
        module: {
            rules: [
                {
                    test: /.(png|jpg|gif)$/i,
                    use: [{
                        loader: 'url-loader',
                        options: {
                            limit: 8192
                        }
                    }]
                }
                ,
                {
                    test: /.js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env']
                        }
                    }
                }
                ,
                {
                    test: /.scss$/,
                    use: [
                        // "style-loader",
                        MiniCssExtractPlugin.loader,
                        "css-loader",
                        "sass-loader"
                    ]
                }
            ]
        }
    }
    
    

    7.2 DefinePlugin-减少代码冗余,定义全局变量

    const path=require('path');
    const MiniCssExtractPlugin=require("min-css-extract-plugin");
    const webpack=require('webpack')
    
    module.exports={
        entry:{
            home:'./home.js'
            about:'./about.js'
            other:'./other.js'
        }, //入口文件
        output:{
            path:path.resolve(__dirname,'dist'),
            filename:'[name].bundle.js' //name->home or about or other
        },
        mode:"development",
        plugins:[
            new MiniCssExtractPlugin({
                filename:"[name].css",//name->home
                chunkFilename:"[id].css"
            }),
            new webpack.DefinePlugin({      'SERVICE_URL':JSON.stringify('http://www.sina.com')
            })//就可以直接在js文件中使用SERVICE_URL中使用
        ],
        module:{
        	rules:[{
        		test:/.scss$/,
        		use:[
        			MinCssExtractPlugin.loader,
        			"css-loader",
        			"sass-loader"
        		]
    		}]
    	}
    }
    
    

    7.3 HtmlWebpackPlugin

    • 目的:帮助我们去生产html文件,我们的js脚本不能独立运行(仅限前端,都知道有node,是可以的独立运行的),所以js必须包含在某个HTML文件中,才能运行。

    • 安装

    npm install --save-dev html-webpack-plugin

    npm install html-webpack-plugin -D

    const path = require('path')
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const devMode = process.env.NODE_ENV !== 'production';
    const webpack=require('webpack')
    const HtmlWebpackPlugin=require('html-webpack-plugin')
    
    module.exports = {
        entry: {
            output: './src/index.js'
        }, //入口文件
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: '[name].bundle.js' //name->home or about or other
        },
        // mode: "production",
        mode: "development",
        plugins: [
            new MiniCssExtractPlugin({
                filename: "[name].[hash].css",//name->home
                chunkFilename: "[id].[hash].css"
            }),
            new webpack.DefinePlugin({
                'SERVICE_URL': JSON.stringify('https://dev.example.com')
            }),
            // new HtmlWebpackPlugin()//base
            new HtmlWebpackPlugin({
                title:"Randy App",
                filename:"index.html",
                template:'template.html'
            })
        ],
        module: {
            rules: [
                {
                    test: /.(png|jpg|gif)$/i,
                    use: [{
                        loader: 'url-loader',
                        options: {
                            limit: 8192
                        }
                    }]
                }
                ,
                {
                    test: /.js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env']
                        }
                    }
                }
                ,
                {
                    test: /.scss$/,
                    use: [
                        // "style-loader",
                        MiniCssExtractPlugin.loader,
                        "css-loader",
                        "sass-loader"
                    ]
                }
            ]
        }
    }
    

    8.热替换-自动刷新

    • 配置完整的webpack项目,启动服务,热替换操作,自动化,页面更新也是自动化

    • 中文文档

    • 英文文档

    • 安装

    npm install webpack-dev-server -D

    const path = require('path')
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const devMode = process.env.NODE_ENV !== 'production';
    const webpack = require('webpack')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
        entry: {
            output: './src/index.js'
        }, //入口文件
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: '[name].bundle.js' //name->home or about or other
        },
        devServer: {
            open:true,
            contentBase: path.join(__dirname, "dist"),//output 路径
            compress: true,//
            port: 3000
            // ,hot:false
            //hot配置是否启用模块的热替换功能,
            //devServer的默认行为是在发现源代码被变更后,
            //通过自动刷新整个页面来做到事实预览,
            
            //而开启hot后,
            //将在不刷新整个页面的情况下通过新模块替换老模块来做到实时预览。
        },
        // mode: "production",
        mode: "development",
        plugins: [
            new MiniCssExtractPlugin({
                filename: "[name].[hash].css",//name->home
                chunkFilename: "[id].[hash].css"
            }),
            new webpack.DefinePlugin({
                'SERVICE_URL': JSON.stringify('https://dev.example.com')
            }),
            // new HtmlWebpackPlugin()//base
            new HtmlWebpackPlugin({
                title: "Randy App",
                filename: "index.html",
                template: 'template.html'
            })
        ],
        module: {
            rules: [
                {
                    test: /.(png|jpg|gif)$/i,
                    use: [{
                        loader: 'url-loader',
                        options: {
                            limit: 8192
                        }
                    }]
                }
                ,
                {
                    test: /.js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env']
                        }
                    }
                }
                ,
                {
                    test: /.scss$/,
                    use: [
                        // "style-loader",
                        MiniCssExtractPlugin.loader,
                        "css-loader",
                        "sass-loader"
                    ]
                }
            ]
        }
    }
    
    {
      "scripts": {
        "start": "webpack-dev-server --hot",
        "build":"webpack",
        "dev":"webpack-dev-server"
      },
      "devDependencies": {
        "@babel/core": "^7.8.4",
        "@babel/preset-env": "^7.8.4",
        "babel-loader": "^8.0.6",
        "css-loader": "^3.4.2",
        "fibers": "^4.0.2",
        "html-webpack-plugin": "^3.2.0",
        "mini-css-extract-plugin": "^0.9.0",
        "node-sass": "^4.13.1",
        "sass": "^1.25.0",
        "sass-loader": "^8.0.2",
        "style-loader": "^1.1.3",
        "url-loader": "^3.0.0",
        "webpack": "^4.41.6",
        "webpack-cli": "^3.3.11",
        "webpack-dev-server": "^3.10.3",
         "file-loader": "^5.1.0",
        "url-loader": "^3.0.0"
      }
    }
    
    

    热启动:npm run start

  • 相关阅读:
    Redis线程模型理解
    策略模式
    Spring Cloud 5大组件介绍
    单例模式
    hotspot虚拟机的调试
    编译虚拟机jvm——openjdk的编译
    mybatis的搭建和注入spring的方式
    springMvc+hibernate的web application的构建
    关于本博客
    本博客已停更
  • 原文地址:https://www.cnblogs.com/RandyField/p/12339672.html
Copyright © 2020-2023  润新知