hmr webpack 不编译_前端修仙路:webpack教程(v4.x)

d50da4f15253eb2801a756fe8f9112cb.png

本质上, webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。

当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个代码块(bundle),webpack默认只具备打包js的能力

名词解释

  1. bundle: 一个或多个编译后的代码块

  2. entry: 入口,webpack编译的入口

  3. output 出口,webpack编译的出口

  4. loader 加载器,webpack默认只支持js的打包,如果需要处理其他类型文件,则需要引入相应的loader。

  5. plugins 插件,可以看做是webpack能力的扩充,用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。

  6. mode 模式,指定开发环境的模式,可以对特定环境的编译进行优化。

  7. HMR 模块热替换(hot module replacement),无需浏览器刷新,即可局部更新代码以及样式。

安装

> npm init -y> npm install webpack webpack-cli

npm init -y npm初始化一个项目,创建package.json

npm install -D webpack webpack-cli 安装webpack开发依赖。

使用

初始项目结构如下:

  • build

  •   webpack.config.js

  • src

  •   module

  •     a.js

  •   index.js

  • package.json

创建webpack的配置文件

// build/webpack.config.jsconst path = require('path');module.exports = {  mode: process.env.NODE_ENV,  entry: '../src/index.js',  output: {    path: path.resolve(__dirname, '../dist'),    filename: 'my-first-webpack.bundle.js'  }};
  1. mode 配置打包环境,取值

  2. entry 打包的入口js文件,可以是多个,多个就填数组。

  3. output 打包编译后出口

    1. path 编译出口目录

    2. filename 编译后js文件名

  4. process.env.NODE_ENV 这个是node的环境变量,由运行的时候决定。

下面瞎写一个入口文件:

// src/index.jsimport say from './module/a'    //随便引入个模块say.sayName();// src/module/a.jsexport default {    name:'hzz',    sayName(){        console.log(this.sayName);    }}

然后再在package.json添加编译命令:

{  "name": "webpack-tutorial",  "version": "1.0.0",  "description": "webpack tutorial",  "main": "index.js",  "author": "terryvvan",  "license": "MIT",  "private": false,  //重点  "scripts": {    "start": "npm run dev",    "dev": "set NODE_ENV=development&&webpack --config ./build/webpack.config.js",    "build": "set NODE_ENV=production&&webpack --config ./build/webpack.config.js"  },  "devDependencies": {    "webpack": "^4.43.0",    "webpack-cli": "^3.3.11"  }}
  1. set NODE_ENV=development 这句命令是windows环境下设置环境变量,目的是为了决定webpack的mode环境,以便其进行特定优化编译。

  2. webpack --config 执行配置文件交给webpack编译。

最后执行命令:

> npm startwebpack-tutorial@1.0.0 start C:\Users\24244\Desktop\study\webpack-tutorialnpm run devwebpack-tutorial@1.0.0 dev C:\Users\24244\Desktop\study\webpack-tutorialset NODE_ENV=development&&webpack --config ./build/webpack.config.jsHash: 8e8662107e05e5c7ab43Version: webpack 4.43.0Time: 243msBuilt at: 2020-05-24 18:46:26  Asset      Size  Chunks             Chunk Namesmain.js  19.5 KiB    main  [emitted]  mainEntrypoint main = main.js[./build/webpack.config.js] 277 bytes {main} [built]    + 2 hidden modules

至此完成最小化打包,我们继续完善这个例子,目前只能打包js,web环境离不开html和css,接下来加入html和css。

css及html支持

<html>  <head>    <meta charset="UTF-8">    <link rel="shortcut icon" type="images/x-icon" href="./favicon.ico">    <title>webpack Apptitle>  head>  <body>      <div id="app">        <p>hello worldp>      div>  body>html>

新建public目录,存放html文件以及一些公共资源,这常在vue-cli和create-react-app的目录结构中看到,该目录下的文件不参与编译,仅仅只是拷贝到输出(output>path)目录。

然后在新增assets目录,存放css或图片等静态资源文件,该目录下的文件会参与编译。

#app{    position: absolute;    left: 0;    right: 0;    bottom: 0;    top: 0;    background: white;    display: flex;    justify-content: center;    align-items: center;    flex-direction: column;}p{    color:blue;}

目前已建立的目录结构如下:

  • build

    • webpack.config.js

  • public

    • favicon.ico

    • index.html

  • src

    • assets

      • app.css    

    • module

      • a.js

    • index.js

  • package.json

为了解析html和css,修改配置文件如下:

const HtmlWebpackPlugin = require('html-webpack-plugin'); //html生成const path = require('path');const CopyWebpackPlugin = require('copy-webpack-plugin'); //复制文件目录let env = process.env.NODE_ENV;        //当前环境let isProd = env=='production';let rootPath = path.resolve(__dirname, '../');  //项目根路径let distPath = path.resolve(rootPath, 'dist');  //项目编译输出路径let srcPath = path.resolve(rootPath, 'src');    //源码路径module.exports = {  mode: env,  entry: path.join(srcPath,'index.js'),  output: {    path: distPath,    filename: 'js/[name].js',    // publicPath: './'  },  resolve: {    extensions: ['.js'], // 自动解析扩展。(import导入文件时可省略此处定义的扩展)    alias: {        '@': srcPath // 在项目中使用@符号代替src路径,导入文件路径更方便    }  },  module: {    rules: [                    //配置loader处理相应文件      {        test: /\.css$/,        //正则匹配导入的css文件        use: [          'style-loader',      //将处理好css文件通过内联方式导入html          'css-loader'         //处理css文件        ]      }    ]  },  plugins:[    new HtmlWebpackPlugin({        //生成html      minify:isProd,    //是否压缩      hash:isProd,      //是否为资源生成hash值,避免缓存      template:path.join(rootPath,'public/index.html') //模板路径,可以是ejs文件    }),    new CopyWebpackPlugin({ //复制public目录的所有文件到dist目录      patterns:[        {from:path.resolve(rootPath,'public'),to:distPath}      ],      options:{}    }),  ]};

安装解析html和css所需依赖,并执行构建:

> npm install -D html-webpack-plugin css-loader copy-webpack-plugin> npm run start

此时,我们的项目已经可以编译html+css+js三大件了,但有一个缺陷,我们现在的项目每次修改只能手动进行编译。我们在使用vue或者react脚手架时,都会自动启用一个开发环境的服务器,便于预览,甚至可以在修改文件时,自动执行编译。

接下来我们加入webpack-dev-server插件:

> npm install -D webpack-dev-server1修改package.json的dev命令,改由webpack的开发服务器启动:"scripts": {    "start": "npm run dev",    "dev": "set NODE_ENV=development&&webpack-dev-server --config ./build/webpack.config.js"  },

修改webpack的配置文件,以支持启动:

//略...module.exports = {    //略...    devServer: {        historyApiFallback: true,   //找不到地址回滚到index.html        contentBase: './dist',  //默认是项目根目录,服务器开启目录即index.html所在目录        // publicPath:'./dist',        progress:true,      //开启进度        compress: isProd,   //开启gzip压缩        host:'localhost',   //主机地址,填局域ip或者0.0.0.0可局域网内访问        hot:true,           //开启热更新,即无需刷新即可更新改动        hotOnly:true,       //只启动热更新,将不会自动刷新页面        port: 9000,         //端口        open: !isProd,      //是否自动打开浏览器        // https: true,     //启用https服务器        overlay: true,      //错误是否显示在页面上        stats:{             //一些状态的提示信息            warnings: true,            errors: true,            errorDetails: true,            colors: true,            performance: true,  //当文件大小超过 `performance.maxAssetSize` 时显示性能提示        },        proxy: {        //开启代理,不需要可以不配置            "/api": {  // /api下请求将被代理                target: "http://localhost:3000", //要代理的域名                pathRewrite: {"^/api" : ""},                // secure: false //关闭安全验证,这样可以使用代理服务器不安全的https证书            }        }    },}

入口文件首行新增:

// src/index.jsif (module.hot) {        //接受热更新,如果是vue单页环境不需要这个也可以    module.hot.accept();}//...省略无关代码

接下来启动项目:

>npm start> webpack-tutorial@1.0.0 start C:\Users\Administrator\Desktop\temp\webpack-tutorial> npm run dev> webpack-tutorial@1.0.0 dev C:\Users\Administrator\Desktop\temp\webpack-tutorial> set NODE_ENV=development&&webpack-dev-server --config ./build/webpack.config.js10% building 1/1 modules 0 activei 「wds」: Project is running at http://localhost:9000/i 「wds」: webpack output is served from /i 「wds」: Content not from webpack is served from ./dist11% building 13/14 modules 1 active C:\Users\Administrator\Desktop\temp\webpack-tutorial\node_modules\babel-loader\lib\index.js!C:\Users\Administrator\Desktop\temp\webpack-tutorial\src\index.jsi 「wdm」: wait until bundle finished: /i 「wdm」: Hash: 6c51adf39d371da68654Version: webpack 4.43.0Time: 3867msBuilt at: 2020-05-27 15:19:42         Asset       Size  Chunks                   Chunk Names   favicon.ico   3.08 KiB          [emitted]    index.html  361 bytes          [emitted]    js/main.js   1.57 MiB    main  [emitted]        mainjs/main.js.map   1.81 MiB    main  [emitted] [dev]  mainEntrypoint main = js/main.js js/main.js.map[0] multi (webpack)-dev-server/client?http://localhost:9000 (webpack)/hot/only-dev-server.js ./src/index.js 52 bytes {main} [built][./node_modules/react-dom/index.js] 1.33 KiB {main} [built][./node_modules/react/index.js] 190 bytes {main} [built][./node_modules/vue/dist/vue.runtime.esm.js] 222 KiB {main} [built][./node_modules/webpack-dev-server/client/index.js?http://localhost:9000] (webpack)-dev-server/client?http://localhost:9000 4.29 KiB {main} [built][./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.51 KiB {main} [built][./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.53 KiB {main} [built][./node_modules/webpack-dev-server/client/utils/createSocketUrl.js] (webpack)-dev-server/client/utils/createSocketUrl.js 2.91 KiB {main} [built][./node_modules/webpack-dev-server/client/utils/log.js] (webpack)-dev-server/client/utils/log.js 964 bytes {main} [built][./node_modules/webpack-dev-server/client/utils/reloadApp.js] (webpack)-dev-server/client/utils/reloadApp.js 1.59 KiB {main} [built][./node_modules/webpack-dev-server/client/utils/sendMessage.js] (webpack)-dev-server/client/utils/sendMessage.js 402 bytes {main} [built][./node_modules/webpack-dev-server/node_modules/strip-ansi/index.js] (webpack)-dev-server/node_modules/strip-ansi/index.js 161 bytes {main} [built][./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built][./node_modules/webpack/hot/only-dev-server.js] (webpack)/hot/only-dev-server.js 2.52 KiB {main} [built][./src/index.js] 662 bytes {main} [built]    + 53 hidden modulesChild HtmlWebpackCompiler:                          Asset       Size               Chunks             Chunk Names    __child-HtmlWebpackPlugin_0    4.6 KiB  HtmlWebpackPlugin_0             HtmlWebpackPlugin_0                    favicon.ico   3.08 KiB                       [emitted]                     index.html  327 bytes    Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0    [./node_modules/html-webpack-plugin/lib/loader.js!./public/index.html] 619 bytes {HtmlWebpackPlugin_0} [built]i 「wdm」: Compiled successfully.

然后webpack会自动打开浏览器,浏览器的控制台会显示下面这句话:

[HMR] Waiting for update signal from WDS...

这个表示webpack-dev-server的热更新已开启,从此改动js,css就不需要重新编译,也不需要刷新浏览器,它会帮你在改动的时候自动更新。

vue支持

这样就够了嘛?不够,来加入vue,安装vue三大件依赖:

> npm install -D vue-style-loader vue-loader vue-template-compiler> npm install vue
  1. vue-style-loader 处理vue组件的style标签

  2. vue-loader 点击右侧传送门,即可前往文档=>传送门

  3. vue-template-compiler 处理vue组件template标签

修改webpack配置以支持vue:

// webpack.config.jsconst VueLoaderPlugin = require('vue-loader/lib/plugin');//...省略无关代码module.exports = {  //...省略无关代码  resolve: {    extensions: ['.js','.vue'], // 解析扩展。    alias: {        '@': srcPath // 在项目中使用@符号代替src路径,导入文件路径更方便    }  },  module: {    rules: [      {        test: /\.vue$/,        use:{            loader: 'vue-loader'        }      },      {        test: /\.css$/,        use: [          'vue-style-loader', //style-loader替换成vue的          'css-loader'         ]      }    ]  },  plugins:[    //...省略无关代码    new VueLoaderPlugin(),  ]}

现在增加一个vue的测试组件:

// src/components/HelloWorld.vue<template>  <div class="root">      hello {{this.name}}  div>template><script>  export default {      name:'HelloWorld',      data(){          return {              name:'vue'          }      }  }script><style>  .root{      color: aquamarine;  }style>

入口文件引入vue组件:

// src/components/HelloWorld.vueimport say from '@/module/a'import '@/assets/app.css'import Vue from 'vue'import HelloVue from '@/components/helloWorld'say.sayName();console.log(1334);new Vue({    el: '#helloVue',    render: h => h(HelloVue)})

至此vue系列加入完毕,运行即可看到效果:

> npm start

react支持

这就够了嘛,不!既然vue加了,作为国内同样流行的react理应也加入进来,我们先来安装依赖:

npm install -D babel-loader @babel/preset-env @babel/preset-react @babel/core @babel/plugin-proposal-class-properties @babel/plugin-proposal-decoratorsnpm install react react-dom
  1. babel-loader 用来处理js

  2. @babel/preset-env 用于支持es6的语法

  3. @babel/preset-react 支持react,不用说

  4. @babel/core 提供给其他插件转码使用

  5. @babel/plugin-proposal-class-properties class支持

  6. @babel/plugin-proposal-decorators 装饰器支持

还有一些其他的babel插件支持就不说了,给个=>传送门

https://www.babeljs.cn/docs/

接下来我们修改webpack的配置文件以支持react:

// webpack.config.js// ...省略无关代码module.exports = {  resolve: {    extensions: ['.js','.vue','.jsx'], // 解析扩展。    alias: {        '@': srcPath // 在项目中使用@符号代替src路径,导入文件路径更方便    }  },  module: {    rules: [      {        // 以 .js 或者 .jsx 结尾的文件, 使用 babel-loader        test: /\.(js|jsx)$/,        // 编译时, 不去node_modules 目录下找        exclude: /node_modules/,        use: {          loader: 'babel-loader',        }      }      // ...省略无关代码    ]  }  // ...省略无关代码}

项目根目录创建babel的配置文件:

// babel.config.jsmodule.exports = {    presets: ["@babel/preset-env", "@babel/preset-react"],    plugins: [        ["@babel/plugin-proposal-decorators", { "legacy": true }],        ["@babel/plugin-proposal-class-properties", { "loose": true }]      ]};

我们来随便写个react组件:

// src/components/HelloReact.jsximport React from 'react'export default class HelloReact extends React.Component {    render() {      return (        <div>          Hello {this.props.name}        div>      );    }  }

入口文件引入react:

// src/index.jsif (module.hot) {    module.hot.accept();     //接受热更新}import say from '@/module/a'import '@/assets/app.css'import Vue from 'vue'import React from 'react'import ReactDOM from 'react-dom'import HelloVue from '@/components/helloWorld'import HelloReact from '@/components/HelloReact'say.sayName();console.log(1334);ReactDOM.render(    "Taylor" />,    document.getElementById('helloReact'));new Vue({    el: '#helloVue',    render: h => h(HelloVue)})

修改index.html:

<html>  <head>    <meta charset="UTF-8">    <link rel="shortcut icon" type="images/x-icon" href="./favicon.ico">    <title>webpack Apptitle>  head>  <body>      <div id="app">        <p>hello worldp>        <div id="helloReact">div>        <div id="helloVue">div>      div>  body>html>

现在我们可以运行了:

npm start

大功告成!

347197a604786917fe36e8e7f3048daf.png

以上示例代码地址:

https://github.com/terryvince/webpack-tutorial.git

如果对你有帮助记得点个star。

尾声

当然在实际工作中,还需添加wepack更多的loader以及plugin的支持才能满足需要,比如webpack的配置文件需要分开,抽离开发环境(webpack.dev.config.js),抽离生产环境(webpack.dev.config.js),抽离基础配置(webpack.base.config.js)。

比如sass支持,需要引入sass-loader,图片处理,需要引入file-loader等等,这些就留给大家去探索。如果实在有兴趣的可以安装笔者写的cli工具,来拉取webpack模板研究,这个webpack模板乃笔者在生产环境中得到检验,目前支持vue以及ts或者多页开发环境。下面给出获取方法:

方法一

通过cli拉取

npm install vvan-cli -gvvan init

vvan-cli 是笔者发布在npm的包,方便平时下载使用。

vvan init 如果不写名字,会通过问询让你确定项目的名字以及其他配置

项目生成好后,你可以在项目根目录的build目录找到所有的配置信息。

方法二

从github地址拉取:

git clone https://github.com/terryvince/webpack-build-template.git

更多高级教程请移步webpack中文网,有能力的可以去读英文官网 ?

f11c131153723e803022172c09471fde.png

ead9fef588db1a27f9293e94f6199442.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值