webpack4.0初探

作者: cb12hx | 来源:发表于2018-03-24 23:05 被阅读867次

    webpack4.0发布了一段时间了,本文稍微研究下

    1.webpack-cli必须

    默认安装了webpack,执行时,会报错,需要装上webpack-cli

    2.不再需要webpack.config.js

    默认情况下,已经不再需要这个配置文件,它已经有了最基本的配置,此时,我们执行了webpack命令,看看效果


    image.png

    一个警告,一个报错,忽略警告,看看报错,应该是需要一个src默认的文件保存路径,加上之后,再运行看看,警告依然在,但是错误没了,也生成了文件,在dist下面


    image.png

    3.mode有development和production模式

    还记得层级的uglify-js之类的plugin吗,webpack4已经不需要了,提供了development和production模式

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

    4.默认对js的支持程度

    class A{
        constructor(){
            alert('cccc')
        }
    }
    new A()
    var B= ()=>{
        alert('arrow function')
    }
    B()
    

    一开始,我用chrome(版本 63.0.3239.132(正式版本) (64 位))和ios11来访问,直接是好了,吓了一跳,以为连babel之类的都不用配置了,后来发现我的Mini2一直ios8,试着访问,alert失效,那肯定是不支持,又用了ie11,还是不支持,所以还是需要配置文件的,所以,webpack4所指的零配置,应该是entry,output,mode,本demo中,是在ios8下报这个错

    TypeError: Map constructor does not accept arguments
    

    从字面来看,应该是Map不支持,我在入口文件import 了babel-polyfill问题解决

    5.css处理

    曾经我们都是用extract-text-webpack-plugin这个来抽去css文件,webpack4中已经废弃了(Unfortunately said plugin does not play well with webpack 4.),推荐的是mini-css-extract-plugin

    6.React hello world

    由上面的结论,我们就可以来实现一个简单的react demo了,要做的事情,需要处理js,需要处理css,那么仍然需要config.js

    const HtmlWebPackPlugin = require("html-webpack-plugin")
    const MiniCssExtractPlugin = require("mini-css-extract-plugin")
    module.exports = {
        module: {
            rules: [{
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: {
                        loader: "babel-loader",
                        options: {
                            presets: [
                                ["env", {
                                    "targets": {
                                        "browsers": ["last 2 versions", "safari >= 7", "iOS >= 8"]
                                    }
                                }], 'react'
                            ],
                            "plugins": [
                                "transform-runtime"
                            ]
                        }
                    }
                },
                {
                    test: /\.html$/,
                    use: [{
                        loader: "html-loader"
                    }]
                },
                {
                    test: /\.scss$/,
                    use: [MiniCssExtractPlugin.loader, "css-loader?modules=true", "sass-loader"]
                }
            ]
        },
        plugins: [
            new HtmlWebPackPlugin({
                template: "./src/index.html",
                filename: "./index.html"
            }),
            new MiniCssExtractPlugin({
                filename: "[name].css",
                chunkFilename: "[id].css"
            })
        ]
    }
    

    这是配置文件,主要是对js和scss做了处理,再看看react部分

    import React, { Component } from "react"
    import ReactDOM from "react-dom"
    import styles  from './main.scss'
    class App extends Component {
        componentDidMount() {
            console.log('ssssss:', styles)
        }
        render(){
          return (
            <div className={styles.test}>
              <p>Hello webpack4.0</p>
            </div>
          )
      }
    };
    export default App;
    ReactDOM.render(<App />, document.getElementById("app"));
    

    这样就实现了一个最简单的react demo

    7. dev server

    一般情况下,开发模式下,我们要启动一个服务,用于监听文件修改时页面的热加载,这个webpack为我们考虑好了,我们只需要按照如下配置即可

    npm i webpack-dev-server --save-dev
    

    然后定义一个命令用于启动服务

    webpack-dev-server --mode development --open
    

    由于我们使用了MiniCssExtractPlugin,这个时候在development下,scss修改,页面是不会刷新的,所以开发模式下,需要去掉css的抽取,改用如下的配置

    use: ["style-loader", "css-loader?modules=true", "sass-loader"] 开发模式
    

    8. redux

    具体的redux的引用请看我以前的一篇文章https://www.jianshu.com/p/abf44b4a4c7c,或者参考https://github.com/chenbin2015/react-redux-es6-quickstart,本模块我们只介绍一些基本对象

    8.1 redux

    • createStore
      用来创建一个store,并注册到provider中
    • combineReducer
      合并reducer
    • bindActionCreators
      将action绑定到组件上
      另外的applyMiddleWare和compose本demo暂不提及

    8.2 react-redux

    • connect
    • Provider

    9. 路由

    路由的原理,可以参考https://www.jianshu.com/p/b66f56c65049,本文中使用react-router-redux,我们就按照官网的demo进行配置吧,看下具体变化

    //没有开启服务端,所以使用hash
    import createHistory from 'history/createHashHistory'
    import { Route } from 'react-router'
    import { ConnectedRouter, routerReducer, routerMiddleware } from 'react-router-redux'
    
    
    import Home from './containers/Home'
    import About from './containers/About'
    import App from './containers/Demo'
    const history = createHistory()
    const middleware = routerMiddleware(history)
    const store = createStore(
        combineReducers({
            reducers,
            router: routerReducer
        }),
        applyMiddleware(middleware)
    )
    
    <Provider store = { store } >
        <ConnectedRouter history={history}>
          <div>
            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
          </div>
        </ConnectedRouter>
      </Provider>
    

    建议还是了解原理吧,这边只是适应引用包的语法糖,没啥好说的

    10. 按需加载

    按需加载的原理,我以前讲过了,参考https://www.jianshu.com/p/b66f56c65049这个吧
    目前react-route提供了react-loadable,这个能很方便地为我们实现按需加载的功能,一步步来即可
    先安装react-router-redux,根据它的语法,我们还需要安装babel的一个插件babel-plugin-syntax-dynamic-import,接下来就是写我们的组件了

    image.png
    我们的组件分成了两部分
    index.js
    import React, { Component } from 'react'
    import Loadable from 'react-loadable'
    import Loading from '../Loading'
    
    const LoadableComponent = Loadable({
      loader: () => import('./entry'),
      loading: Loading,
    });
    
    export default class App extends Component {
      render() {
        return <LoadableComponent/>;
      }
    }
    

    其中的loader是具体的组件内容,loading官方的说法是一个placeholder(loading is a placeholder component to show while the real component is loading),这个具体的有时间再研究下,目前看来就是在路由切换时有一个过渡的过程,主要的是loader,这个就是去引用具体的组件内容,接下来,我们执行下生产模式


    image.png

    图中的0和1就是按需生成的js文件,路由变化时,会去加载不同的js

    目前,实现了开发模式和生产模式的简单配置,如果要用到线上,还需要eslint,immutable啥的,这里就不展开了,其实webpack4的出现,也是对曾经版本的继承与优化,要不断地随着技术的发展来提升自己即可,代码放到这里

    参考资料:https://www.valentinog.com/blog/webpack-4-tutorial/

    相关文章

      网友评论

        本文标题:webpack4.0初探

        本文链接:https://www.haomeiwen.com/subject/jtvqcftx.html