webpack自动化架构入门

2,600 阅读5分钟

目录

  • 前言
  • webpack起步
  • 配置webpack
  • 构建本地服务器
  • 配置HTML模板
  • 配置es6
  • 配置react、jsx
  • 配置css、less

前言

第一次打算学习自动化的时候是参照的一个老哥的文章,没想到现在版本更新太快,那篇文章已经跑不起来了,所以我在这重新写一篇最新版的搭建文章,怀念一下我老哥。

原文地址

webpack起步

1、初始化项目

mkdir react-cli && cd react-cli
npm init -y

第一句: 生成react-cli文件夹并进入

第二句: -y 的含义:yes的意思,在init的时候省去了敲回车的步骤,生成的默认的package.json

2、安装webpack

npm install webpack -D

第一句: -D 是 --save-dev 的简写,是指安装模块并保存到 package.json 的 devDependencies中,主要在开发环境中的依赖包. 如果使用webpack 4+ 版本,还需要安装 webpack-cli。

npm install -D webpack-cli

3、建立项目解构

react-cli
|--package.json
|--/dist
   |--index.html
|--/src
   |--index.js

index.html

<!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="main.js"></script>
</body>
</html>

index.js

document.querySelector('#root').innerHTML = 'inke';

我们就可以使用webpack的打包功能了

node_modules/.bin/webpack src/index.js --output dist/bundle.js --mode development

执行出入口配置都在命令中。

执行成功之后会发现dist文件夹下会多出一个main.js,这时可以打开dist目录下的html文件,可以看到文本inke。

配置webpack

1、配置文件。

根目录下建立webpack.config.js

webpack.config.js

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    }
};

走config配置之后再进行打包命令,这时会缺少出入口的配置。如下

node_modules/.bin/webpack --mode production

一样是dist文件夹中生成main.js,打开index.html看到文本inke

2、配置script脚本

package.json 添加一个 npm 脚本

"scripts": {
    "build": "webpack --mode production"
},

运行,即可进行打包

npm run build

构建本地服务器

webpack-dev-server 提供了一个简单的 web 服务器,并且能够实时重新加载。

1、安装 webpack-dev-server

npm install -D webpack-dev-server

新增webpack配置。

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    },
    // 新增
    devServer: {
        contentBase: "./dist", // 本地服务器所加载的页面所在的目录
        historyApiFallback: true, // 不跳转
        inline: true, // 实时刷新
        port: 3000, // 启用端口
        open: true, // 自动打开浏览器
    }
};

与打包一样,配置NPM scripts脚本

"start": "webpack-dev-server --open --mode development"

执行

npm run start

即可看到本地启动了3000端口,访问

http://localhost:3000/

我们又再次看到了inke文本。

启动webpack-dev-server后,在目标文件夹中是看不到编译后的文件的,实时编译后的文件都保存到了内存当中。因此使用webpack-dev-server进行开发的时候都看不到编译后的文件

2、启用热更新

先来科普一下定义,关于 WDS 热更新,有以下几点:

(1)WDS 不刷新整个页面;
(2)WDS 不输出文件,而放在内存中(没有磁盘IO,速度更快);
(3)使用 HotModuleReplacementPlugin 插件(webpack自带);

配置一个webpack自带的插件并且还要在主要js文件里检查是否有module.hot

webpack.config.js

const path = require('path');
// 新增
const webpack = require('webpack');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        contentBase: "./dist", // 本地服务器所加载的页面所在的目录
        historyApiFallback: true, // 不跳转
        inline: true, // 实时刷新
        port: 3000,
        open: true, // 自动打开浏览器
        hot: true // 开启热更新-新增
    },
    // 新增
    plugins:[
        //热更新
        new webpack.HotModuleReplacementPlugin()
    ],
};

src/index.js

document.querySelector('#root').innerHTML = 'inke';

if (module.hot){
    //实现热更新
    module.hot.accept();
}

热更新允许在运行时更新各种模块,而无需进行完全刷新

重启一下项目,看一下效果。动态修改inke文本,即可进行热更新。

配置HTML模版

科普,为什么要用HTML模板

The HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader.

1、安装html-webpack-plugin

npm install -D html-webpack-plugin

添加webpack配置

webpack.config.js

...
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        // 添加hash可以防止文件缓存,每次都会生成4位hash串
        filename: 'main.[hash:4].js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        ...
    },
    plugins:[
        new webpack.HotModuleReplacementPlugin(),
        // 新增
        new HtmlWebpackPlugin({
            template: './src/index.html',
            hash: true, // 会在打包好的bundle.js后面加上hash串
        })
    ],
};

我们把dist文件夹中的index.html移动到src中,当成模板使用。

清空dist,我们重新打包试试看

这里对index.html是模板生成的,刚才配置的hash已经配置上去了。

如果你进行改动,每次的hash值是不一样的,这样会有一个问题。dist文件中 main.js文件会越来越多。所以我们需要一个打包之前清空dist文件夹的一个Plugins.

2、安装 clean-webpack-plugin

npm install -D clean-webpack-plugin

配置webpack

webpack.config.js

...
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        // 添加hash可以防止文件缓存,每次都会生成4位hash串
        filename: 'main.[hash:4].js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        ...
    },
    plugins:[
        ...
        new CleanWebpackPlugin()
    ],
};

这样的话每次打包就不会多出文件了。

编译es6

这里我们采用babel8的配置。

大概的配置是这个样子

webpack 3.x | babel-loader 8.x | babel 7.x

我们来具体安装

npm install -D babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env

webpack.config.js

...

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.[hash:4].js',
        path: path.resolve(__dirname, 'dist')
    },
    // 新增babel-loader解析。
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            }
        ]
    },
    ...
};

重启一下项目,我们在src/index中试着写一些es6语法。你会发现,会正常进行编译。

配置react、jsx

安装react 及 react-dom

npm install -D react react-dom

安装相应babel

npm install -D @babel/preset-react

根目录下创建.babelrc配置文件

.babelrc

{
    "presets": ["@babel/preset-react"]
}

这样我们就可以引用react并且正常编译了。

修改一下我们的业务代码

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
    <App />,
    document.querySelector('#root')
);

if (module.hot){
    //实现热更新
    module.hot.accept();
}

src/App.js

import React from 'react';

class App extends React.Component{
    render() {
        return (
            <div>inke</div>
        );
    }
}
export default App;

重启一下项目,我们会发现,项目正常运行,解析成功。

配置css、less

这里想一个问题,如果react直接

import './App.css';

class App extends React.Component{
    render() {
        return (
            <div className="root">inke</div>
        );
    }
}
export default App;

这样会有什么问题?

因为jsx的语法去掉后react组件是这个样子的。

className是js语法,如果我们直接引入css是无法直接进行装饰的。

1、安装css 相应loader

npm install -D css-loader style-loader url-loader

分别为,css解析,style-loader 的作用是把转码后的css文件插入到相应的 文件中去,样式内url地址解析。

修改webpack配置

module: {
    rules: [
        ...,
        {
            test:/\.(png|jpg|gif)$/,
            use:[
                "url-loader"
            ]
        },
        {
            test: /\.css$/,
            exclude: /node_modules/,
            use: [
                "style-loader",
                "css-loader"
            ]
        }
    ]
},

这里注意一点

loader的加载顺序是从右往左。这里的编译顺序是先用css-loader将css代码编译,再交给style-loader插入到网页里面去。所以css-loader在右,style-loader在左。

然后我们启动项目,再引入一下css文件,就可以使用样式了。

接下来解析less

2、安装less-loader

npm install -D less-loader

修改webpack配置

module: {
    rules: [
        ...,
        {
            test:/\.less$/,
            use:[
                "css-loader",
                "style-loader",
                "less-loader",
            ]
        }
    ]
},

END

这样我们就有了一套最基本的react自动化框架。

修改框架就如改装车,接下来我们还需要去进行改装。

一辆车光能跑是不够的,还需要跑的又快又好。

下一篇,我们进行改装。