webpack 及 模块化总结

webpack安装

  1. 安装 node & npm(因为webpack是基于node开发的)
  2. 通过 npm / yarn 的方式来安装 webpack 
    安装方式: 
    • 全局安装 
      • npm install -g webpack
      • -g : global 全局 
        • 会装在npm默认目录
        • 好处:只需要安装一次,本机中任何项目都可以直接使用
        • 缺点:如果本机项目中所依赖的webpack版本不一致会有一些问题。
        • 官方推荐安装 本地(根据当前项目来安装)
    • 本地安装 
      • npm install –save-dev webpack
      • 可在node_modules 目录中查找;
      • 不同项目可使用不同版本。

模块化

  • 把具有一定独立功能的代码放到一个单独的文件中,每一个文件就是一个模块。
  • 优势:管理方便、易于复用
  • 解决:项目开发过程中的冲突、依赖

node出现以后,node必须有模块化,node实现了一个简易的模块框架,并流行起来,同时为其定义一些标准: 
CommonJS规范 
CommonJS规范是适合使用在服务端的,是同步加载,客户端(浏览器)并不适合使用,所以后来有人就参考CommonJS规范定义一些适用于web的模块化规范:

  • 1.AMD(Asynchronous Module Definition),前置依赖。 
    • 适用于浏览器。
    • 基于AMD的requireJS模块化库
  • 2.CMD(Common Module Definition),CMD则是依赖就近。 
    • 适用于服务器
    • 基于CMD的seaJS模块化库

注意:自从出来后ES6,AMD及CMD基本不用了,而是用ES6中自带的模块化。

ES6模块化

  • 基本规则 
    • 1:每一个模块只加载一次, 每一个JS只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取。 一个模块就是一个单例,或者说就是一个对象;
    • 2:每一个模块内声明的变量都是局部变量,不会污染全局作用域;
    • 3:模块内部的变量或者函数可以通过export导出;
    • 4:一个模块可以导入别的模块
  • 语法 


- 导入:require、ES6->import 
http://www.ecma-international.org/ecma-262/8.0/index.html#table-42!

说明: 
1. export var a=100,那么对应的写法可以用*号的方式去导入,如import * as m1 from './2';;“as m1”意思是取一个别名叫做“m1”,或者import {a} from './2'; 
2. 用*号的导入方式,对应的导出方式可以是任意的。它得到的是一个Object对象 
- 1.js:import * as m1 from './2';,“./2”实际是“./2.js”,可不写后缀。 
- 2.js:export var a=120; 
 
3. 举例: 
- 1.js:

        <code>
            / 导出一组数据
            var a = 100;
            var b = 200;
            var c = function() {};
            export {a, b, c}
        </code>
- 2.js: ``` import {a, b, c} from './2';```</br>
也就是说如果要用{}的形式导入,那么接收的时候就需要注意:导出的名字和接收的名字是对应的,类似解构赋值。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Babel是一个javascript编译器,也是用node写的,可以将ES6+转换成Es5,但并不解析代码中的 import 或 require 指令。因此,我们需要一个打包工具,可用webpack。

webpack配置

webpack可以将AMD、CMD及ES6模块化代码编译成CommonJS。

  • 1.图示: 

  • 2.核心概念

    • 1.入口(entry) 
      • entry:指定我们的项目打包文件的入口文件
      • entry可以接收:[string, array, object]三种类型。
      • 如果我们的应用程序只有一个入口的时候,可以直接使用字符串形式
      • 如果我们的程序有多个入口,那么可以使用数组或者对象形式
      • 单文件:一个入口
      • 单文件多入口:数组:index.html 加载了两个或多个js
      • 多文件多入口:对象 
        //entry: ‘./src/1.js’,
    • 2.输出(output):指定打包后的文件生成配置

      • 1.打包后的文件存放的目录:  
         path: path.resolve(__dirname, “dist”), 
        • __dirname : 常量,返回当前文件所在的绝对路径
        • path.resolve:返回(处理)不同操作系统的绝对路径问题
      • 2.生成后的文件名:

        • (1)对于单个入口起点,filename 会是一个静态名称。filename: ‘bundle.js’;
        • (2)当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用以下一种替换方式,来赋予每个 bundle 一个唯一的名称:

          • a.入口名称: filename: “[name].bundle.js”;
          • 、、、、、、
          • d.使用基于每个 chunk 内容的 hash:filename: “[chunkhash].bundle.js” 
            注意:使用hash值做文件名,是为了使每次打包生成的文件的文件名不一样,解决JS缓存问题。

            <code>
                const webpack=require("webpack");
                const path=require("path");
                module.exports={
                    entry:{
                        a:"./src/1.js"
                    },
                    output:{
                        path:path.resolve(__dirname,"dist"),
                        filename:'bundle.js'
                    }
                };
            </code>
            
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
    • 3.loader

      • (1) 文件打包预处理器,webpack首先会去加载指定文件(css、js、html、txt、png等)各种资源文件,然后进行打包,但是webpack本身只能处理js,像css被打包后可能就会运行出错,Loader就派上用场了,Loader其实就是打包预处理器。 
        预处理:预先处理,webpack会调用各种Loader对非js的资源进行预先处理,处理完成(处理成js能够识别的数据)以后交给webpack进行打包。

      • (2) 在使用loader之前需要安装指定的loader:npm install loader。

      • (3)loader 也能够使用 options 对象进行配置。
      • (4)在 webpack.config.js 文件中进行配置: 
        rules:配置Loader加载和处理规则;

        • test: /\.txt$/ 
          被加载的资源文件的后缀,
        • use: ‘raw-loader’; 
          当加载的资源满足test的时候,调用use指定的loader去该资源进行解析处理。

          <code>
              {
                  ...,
                  //配置第三方模块,比如Loader就在这里配置
                  module: {
                      rules: [
                          //每一个规则是一个对象
                          {
                              test: /\.txt$/,
                              use: 'raw-loader'
                          }
                      ]
                  }
              }
          </code>
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
      • (4)常用的loader

        • (1)raw-loader:处理源数据;
        • (2)file-loader: 解析并返回文件的路径;

          <code>
              {
               test: /\.png$/,
               //use: 'file-loader'
               use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]'
                        }
                    }
                ]
              }
          </code>
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
        • (3)url-loader:像 file loader 一样工作,但如果文件小于限制,可以返回 data URL

          <code>
              {
                  test: /\.(png|jpg|gif)$/,
                  use: [
                    {
                        loader: 'url-loader',
                        options: {
                            // 设置小于limit值生成dataURL,否则生成url
                            limit: 819200
                        }
                    }
                  ]
              }
          </code>
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
        • (4)css-loader:解析 CSS 文件后,使用 import 加载,并且返回CSS代码;
        • (5)style-loader:将模块的导出作为样式添加到DOM中;

          <code>
              {
                test: /\.css$/,
                use: [
                   // 从下向上执行,所以别写反了!!!
                    'style-loader',
                    'css-loader'
                ]
              }
          </code>
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
        • (5)json-loader 
          注意:webpack >= v2.0.0 默认支持导入 JSON 文件,不需再下载json的loader。
    • 4.插件(plugins) 
      和Loader类似,但是他是打包后执行,对打包后的文件做进一步的处理。

      • 压缩插件:webpack.optimize.UglifyJsPlugin是webpack的核心插件,是自带的,直接使用。 
        UglifyJsPlugin与webpack.optimize.UglifyJsPlugin功能相同,但是需要安装插件才能用。
      • ExtractTextWebpackPlugin:从 bundle 中提取文本(CSS)到单独的文件。 
        如下文代码所示,它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。
  • 2.配置:webpack.config.js

    <code>
        const path = require('path');
        const webpack = require('webpack');
        const ExtractTextPlugin = require("extract-text-webpack-plugin");
    
        module.exports = {
            entry: {
                 UglifyJSPlugin: './src/UglifyJSPlugin.js'
            },
            output: {
    
                path: path.resolve(__dirname, "dist"),
                filename: '[name].bundle.js',
                //filename: '[chunkhash].bundle.js'
    
                // 设置打包后的资源的加载
                publicPath: "./dist/"
            },
            module: {
                rules: [
                    {
                        test: /\.css$/,
                        use: ExtractTextPlugin.extract({
                            fallback: "style-loader",
                            use: "css-loader"
                        })
                    }
                ]
            },
            // 插件配置
            plugins: [
                new webpack.optimize.UglifyJsPlugin(),
                new ExtractTextPlugin("styles.css")
            ]
        };
    </code>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

本地webpack运行

  • 方法一:

    • 1.在 package.json 添加一个 npm 脚本(npm script);

      <code>      
          {
            ...
            "scripts": {
              "build": "webpack -w"
            },
            ...
          }
      </code>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 2.运行“npm run build”命令,可得到如下图所示: 
  • 方法二: 
    在当前目录下,运行“.\node_modules.bin\webpack -w”命令。

注意:”webpack -w”中的“-w”命令是监听相关文件是否被修改,若修改则自动重新运行webpack,不用再自己手动重启。

全局webpack运行

在当前目录下,运行“webpack -w”命令。

模块热替换

模块热替换,Hot Module ReplaceMent(HMR)。

  • 可以在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面。效果上就是界面的无刷新更新。
  • 这个功能主要是用于开发过程中,对生产环境没有什么帮助。
  • 过程: 
    • (1)首先需要安装Webpack-dev-server,一个轻量的node.js express服务器。 
      “npm install webpack-dev-server –save-dev” 
      注意:Webpack-dev-server十分小巧,这里的作用是用来伺服资源文件,不能替代后端的服务器。

复制本目录下的 package.json 和 webpack.config.js 文件 
// package.json

<code>
    {
      "name": "003",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "webpack-dev-server --env development",
        "dev": "webpack-dev-server --env development",
        "build": "webpack --env production"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "html-webpack-plugin": "^2.28.0",
        "webpack": "^2.3.2",
        "webpack-dev-server": "^2.4.2"
      }
    }
</code>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

// webpack.config.js

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

    module.exports = {
      devServer: {
        host: process.env.HOST, // Defaults to `localhost`
        port: 8080, // Defaults to 8080
      },
      entry: {
        app: "./app/app.js",
      },
      output: {
        path: path.resolve(__dirname,"build"),
        filename: '[name].js',
      },
      plugins: [
        new HtmlWebpackPlugin({
          title: 'hot replace',
        }),
      ],
    };
</code>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

npm i

npm run dev 或者 npm run start 这些可以在 package.json 中配置

浏览器打开 localhost:8080 端口号可以在webpack.config.js 中配置

热模块打包的资源是存在于内存中的 

使用热模块能为我们的开发带来很多便利

转自:https://blog.csdn.net/qianxing111/article/details/78525321

猜你喜欢

转载自blog.csdn.net/gloria_chenjing/article/details/80530403