Webpack掉坑之路(1)——HelloWorld(基于npm,react)

前言:

基于ES6风格的React以及较新版本的webpack(4.x)和babel等,旨在搬砖和整理,为初学者和自己提供参考,可能存在许多不足之处,请多指教。

1. 初始化:

首先创建文件夹webpack_demo,然后执行命令npm init,进行初始化:

> npm init

2. 创建工程目录:

目录内包括app,config以及public,分别用于存放源代码文件、配置文件以及输出文件。创建目录结构如下:(在cmd控制台下,执行tree命令)

D:\webpack_demo> tree .
卷 software 的文件夹 PATH 列表
卷序列号为 8CFF-7734
D:\WEBPACK_DEMO
├─app
├─config
└─public

3. 创建HTML首页

在public目录下,创建一个index.html,作为主页,将存放app目录下的打包输出文件bundle.js,代码如下:

<!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>Document</title>
</head>
<body>
    <div id="root"></div>
    <script src="bundle.js"></script>
</body>
</html>

4. 编写入口文件main.js

在app目录下,创建一个main.js,暂时作为主要入口(entry),该文件将被打包为bundle.js,输出到public目录下,代码如下:

import React,{Component} from 'react';
import ReactDOM from 'react-dom';

class App extends Component{
    render(){
        return (
            <div>Hello, world!</div>
        );
    }
}

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

此时,需要安装一下react和react-dom包,命令如下:

> npm install --save react react-dom

5. webpack配置(config/webpack.config.js)

webpack配置好后,即可用webpack命令打包app中的源码,首先需要安装webpack相关依赖包,命令如下:

> npm install --save-dev webpack webpack-cli

然后在config目录下创建一个配置文件webpack.config.js,内容如下:

const path = require('path');               
const base = path.join(__dirname, '..');    

module.exports={
    devtool: 'eval-source-map',
    entry: path.resolve(base,'app/main.js'),
    output:{
        path: path.resolve(base, 'public'),
        filename: 'bundle.js'
    },
    devServer:{
        contentBase: path.resolve(base, 'public'),
        historyApiFallback: true,                   
        inline: true,                               //实时更新
    },
    module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ["@babel/preset-env","@babel/preset-react"],
                plugins: [require('@babel/plugin-proposal-object-rest-spread')]
              }
            }
          }
        ]
    }
};

由于此处用到了babel,而且main.js以es2016的编码方式,需要用babel来进行转换,以兼容之前版本的es,依赖包安装命令如下:(https://www.npmjs.com/package/babel-loader)

> npm install -D babel-loader @babel/core @babel/preset-env @babel/preset-react

6. 添加启动脚本命令行

在package.json中,向"scripts"项添加执行webpack打包命令:

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack --config config/webpack.config.js"
  },

配置完毕后,执行命令npm start,可以进行打包,打包后我们能够看到public目录下多出了一个bundle.js的文件,说明打包成功。内容大概如下所示:

>npm start

> webpack_demo@1.0.0 start D:\webpack_demo
> webpack --config config/webpack.config.js

Hash: e5644b2f4476f963bdc1
Version: webpack 4.20.2
Time: 934ms
Built at: 2018-09-26 23:19:52
    Asset      Size  Chunks             Chunk Names
bundle.js  1.87 MiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/main.js] 2.66 KiB {main} [built]
    + 11 hidden modules

7. 实现页面实时更新

为了能够在编码的同时实时更新前端页面,我们需要安装webpack-dev-server
webpack-dev-server的依赖包安装命令如下:

> npm install --save-dev webpack-dev-server

然后在package.json文件对应的"scripts"中,添加一行执行脚本命令:

...
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack --config config/webpack.config.js",
    "server": "webpack-dev-server --open --config config/webpack.config.js"
  },
...

8. 启动服务器

执行命令npm run server,具体的服务器配置信息如上面的webpack.config.js中的"devServer"。 执行结果如下:

D:\webpack_demo>npm run server

> webpack_demo@1.0.0 server D:\VictorLin\workspace\webpack_demo
> webpack-dev-server --open --config config/webpack.config.js

i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from D:\webpack_demo\public
i 「wds」: 404s will fallback to /index.html
i 「wdm」: wait until bundle finished: /
i 「wdm」: Hash: e734530a0f196c5a077c
Version: webpack 4.20.2
Time: 1218ms
Built at: 2018-09-26 23:31:14
    Asset      Size  Chunks             Chunk Names
bundle.js  2.69 MiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/main.js] 2.66 KiB {main} [built]
[./node_modules/html-entities/index.js] 231 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/node-libs-browser/node_modules/punycode/punycode.js] 14.3 KiB {main} [built]
[./node_modules/querystring-es3/index.js] 127 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/url/url.js] 22.8 KiB {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 7.78 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.58 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {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]
[0] multi (webpack)-dev-server/client?http://localhost:8080 ./app/main.js 40 bytes {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./node_modules/webpack/hot/emitter.js] (webpack)/hot/emitter.js 77 bytes {main} [built]
    + 22 hidden modules
i 「wdm」: Compiled successfully.

如果执行成功的话,会自动弹出已经将打包好的public/bundle.js的public/index.html页面,并显示"Hello, world!"字眼,结果如图:


helloworld!.jpg

我们可以对app/main.js进行修改,比如添加几个感叹号:

//app/main.js
...
class App extends Component{
    render(){
        return (
            <div>Hello, world!!!!!!!</div>
        );
    }
}
...

然后保存,会看到控制台会继续执行编译:

i 「wdm」: Compiling...
i 「wdm」: Hash: c771406eb303106ec693
Version: webpack 4.20.2
Time: 103ms
Built at: 2018-09-26 23:33:50
    Asset      Size  Chunks             Chunk Names
bundle.js  2.69 MiB    main  [emitted]  main
Entrypoint main = bundle.js
[./app/main.js] 2.66 KiB {main} [built]
    + 36 hidden modules
i 「wdm」: Compiled successfully.

过程中包含了执行打包、index.html引用bundle.js,结果如图,确实是多了几个感叹号:


helloworld!!!!!!!.jpg

添加style/css loader支持

命令如下:

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

webpack.config.js配置如下

//其他配置...
module:{
  rules:[  
        //其他配置... ,
        {   
               test: /\.css$/,
               use: [
                   {
                       loader: "style-loader",
                   },
                   {
                       loader: "css-loader",
                   }
               ]
           }
      ]
}

如此便可以在app目录下创建一个css文件,然后让main.js中的组件引用,结果如图:


helloworld!!!!!!!_with_css.jpg

绑定本地IP

在devServer中添加一行host即可绑定本地IP,否则默认启动的服务器只绑定本地的localhost(127.0.0.1),示例如下:

//其他配置项...
    devServer: {
        host: "192.168.4.24",
        port: 3001,
        //其他配置项...
    },

结束语:

都是照搬大佬们的东西,并没有什么原创的,但也不至于抄袭文字,仅供自己和其他初学者学习,有不足之处,请多多指教。更详细教程请参考:
https://segmentfault.com/a/1190000006178770

附录:

1. package.json

package.json中的内容,包括本文中所使用到的各个依赖包及其版本:

//package.json
{
  "name": "webpack_demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack --config config/webpack.config.js",
    "server": "webpack-dev-server --open --config config/webpack.config.js"
  },
  "author": "Victor",
  "license": "ISC",
  "dependencies": {
    "react": "^16.5.2",
    "react-dom": "^16.5.2"
  },
  "devDependencies": {
    "@babel/core": "^7.1.0",
    "@babel/preset-env": "^7.1.0",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.2",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.1",
    "webpack-dev-server": "^3.1.9",
    "css-loader": "^1.0.0",
    "style-loader": "^0.23.0"
  }
}

2. webpack.config.js

//config/webpack.config.js
const path = require('path');
const base = path.join(__dirname, '..');

module.exports={
    devtool: 'eval-source-map',
    entry: path.resolve(base,'app/main.js'),
    output:{
        path: path.resolve(base, 'public'),
        filename: 'bundle.js'
    },
    devServer:{
        contentBase: path.resolve(base, 'public'),
        historyApiFallback: true,
        //host: "192.168.4.24",              //配置ip
        //port: 3000,                              //配置端口
        inline: true,                               //实时更新
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ["@babel/preset-env","@babel/preset-react"],
                        plugins: [require('@babel/plugin-proposal-object-rest-spread')]
                    }
                }
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader: "style-loader",
                    },
                    {
                        loader: "css-loader",
                    }
                ]
            }

        ]
    }
};

初始项目的github如下地址,基于React和Antd,只需执行初始化命令(npm/yarn install)即可使用:
https://github.com/DeepbigSheng/ReactDemoBasedOnAntd

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,504评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,898评论 1 300
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,218评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,322评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,693评论 3 290
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,812评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,747评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,476评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,700评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,190评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,541评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,206评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,129评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,903评论 0 199
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,894评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,748评论 2 274

推荐阅读更多精彩内容