前端工程化 09 - 基于Webpack工作流搭建前端工程

前端工程化 09 - 基于Webpack工作流搭建前端工程

在上一章还是使用Gulp来启动Webpack的任务,在这一章发现这个教程的很多地方都过期了,尤其是Webpack+Babel的地方。 而且Webpack现在越来越流行,因此这一章开始转向使用Webpack来构建工作流。 Babel做的事情,就像PostCss对CSS做的事情,用一些浏览器并不能解析组

在上一章还是使用Gulp来启动Webpack的任务,在这一章发现这个教程的很多地方都过期了,尤其是Webpack+Babel的地方。 而且Webpack现在越来越流行,因此这一章开始转向使用Webpack来构建工作流。 Babel做的事情,就像PostCss对CSS做的事情,用一些浏览器并不能解析组织结构来编写JavaScript代码,以及自动解决浏览器兼容性问题。 Webpack也支持各种组件,就像Gulp的插件一样,所以来试着全部用Webpack来搭建CSS+JS的工作流,目标就是搭建Webpack 4.0 + Vue2.x的开发环境。
  1. 以Webpack作为前端工作流的基础
  2. 入口起点
  3. Loader
  4. Plugin
  5. DevServer

Webpack

一步一步通过IDE来进行实验。WebStorm新建Node.js项目,自动选择Node.js和NPM版本,创建一个空项目。 项目目录下会自动执行npm init,自动创建package.json。 然后通过NPM安装,npm i -D表示install --save-dev
npm i -D webpack
安装了4.32.0版本。Webpack 4.0以上版本分开了命令行工具和插件本身,所以还需要安装:
npm i -D webpack-cli
安装了webpack-cli 3.3.2版本。 推荐将Webpack安装在本地项目,这样可以避免版本冲突。

入口起点与输出

所谓入口起点就是一个js文件,Webpack把这个文件当成起始的地方,逐步解析依赖。 使用webpack.config.js文件进行配置。 输入和输出如果不指定,都有默认位置:
  1. 默认到./src/index.js目录寻找入口
  2. 默认输出到./dist/main.js文件
具体写配置:
const path = require('path');

module.exports = {
    entry: './script/index.js',
    output: {
        path: path.resolve(__dirname,"dist/script"),
        filename: "app.js"
    }
};
这个表示入口在项目根目录的script/index.js,输出在拼接的项目目录/dist/script下,文件名叫做app.js 拼接字符串的时候一定要注意,不能写成/dist/script,别带最前边的反斜杠。 随便建点入口和出口文件,试验了一下,有个坑:
  • 导入的如果不是库,需要指定具体的js文件,比如var show = require("./show.js");不能写成require("show"),webpack无法解析。

Loader

Loader就是让Webpack支持其他类型文件的工具。 Webpack本身只支持JS文件,如果要处理其他,就必须要使用Loader。 使用Loader的时候,必须要显式写配置。
const path = require('path');

module.exports = {
    //设置模式,可以是development或者production
    mode: "development",

    // 入口和输出部分
    entry: './script/index.js',
    output: {
        path: path.resolve(__dirname, "dist/script"),
        filename: "app.js"
    },

    //loader部分
    module: {
        rules: [
            {
                //匹配文件类型
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    }
};
这里使用了一个loader,用于让Webpack支持CSS文件打包。 每个Loader对象放在module-rules,有两个属性,一个是遇到指定后缀名称的资源,一个是用哪个loader进行处理。 处理的结果是CSS资源的样式,被包含在了JS文件里,动态生成了Head中的Style标签,所以样式依然生效。 这样做感觉有点高度耦合和浪费资源,所以还可以使用Plugin来单独生成CSS文件。

Plugin

与Loader能打包多种文件不同,Plugin是用来扩展Webpack的功能。 注意,看了extract-text-webpack-plugin官网: Since webpack v4 the extract-text-webpack-plugin should not be used for css. Use mini-css-extract-plugin instead. 要么安装这个插件,要么按照下边的办法: 需要安装npm i -D extract-text-webpack-plugin@next,注意一定要是next,然后使用loader加载,使用plugin处理:
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    // 入口和输出部分
    entry: './script/index.js',
    output: {
        path: path.resolve(__dirname, "dist/script"),
        filename: "app.js"
    },

    //loader部分
    module: {
        rules: [
            {
                //匹配文件类型
                test: /\.css$/,
                //调用了新的插件的方法,这里使用了css-loader
                loaders: ExtractTextPlugin.extract({
                    use: ['css-loader']
                })
            }
        ]
    },

    //插件部分
    plugins: [
        new ExtractTextPlugin({
            filename: "[name].css"
        })
    ]
};
plugins是一个数组,数组每一个元素都是一个插件的实例。发现不支持[contenthash:8]这种写法了,无奈就先直接用了名称。 如果用
const path = require('path');
const ExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    // 入口和输出部分
    entry: './script/index.js',
    output: {
        path: path.resolve(__dirname, "dist/script"),
        filename: "app.js"
    },

    //loader部分
    module: {
        rules: [
            {
                //匹配文件类型
                test: /\.css$/,
                //调用了新的插件的方法,这里使用了css-loader
                use: [
                    {
                        loader: ExtractPlugin.loader,
                    },
                    'css-loader'
                ]
            }
        ]
    },

    //插件部分
    plugins: [
        new ExtractPlugin({
            filename: "[name].css"
        })
    ]
};

DevServer

Webpack也能做到实时预览加载,通过WebSocket刷新页面。来看一下如何配置。 先要安装服务器:
npm i -D webpack-dev-server
然后在项目根目录执行:webpack-dev-server
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:\Coding\sites\webpackworkflow
服务器直接就启动了。但是会发现没有样式,打开console看,会发现404找不到JS文件。这是因为DevServer不会理会配置文件中的output-path路径,而是会把编译后的文件都放在内存中,对应的就是根目录。 所以要把index.html中的js和css文件链接都修改成直接就在根目录下,比如:
<link rel="stylesheet" href="main.css">
<script src="app.js"></script>
这样就可以正常显示了。不过要注意的是,更新index.html并不能触发自动更新,这是因为Webpack监听的对象是以entry为起点的,不包含在相关依赖内的文件不会被监听。而且单页面应用基本上就加载一个外层框架元素,不大更改HTML。 还可以使用webpack-dev-server --hot来启用模块热替换,刷新的效果更好。

SourceMap

DevServer还有个功能非常方便调试,就是使用 webpack-dev-server --devtool source-map参数,之后在Chrome开发工具中就能查看Source,方便调试。 这里自己试验了一下好像Sources中没有显示。 不管怎么说,现在已经初步搭建好了一个CSS和JS直接处理的程序,剩下就是加上各种可以采取高级编写手段的插件,比如post-css和Babel等工具,来搭建一个基础的前端工具流了。另外架构师朋友说为了Vue的话还可以直接研究Vue-cli,先都记下来。
LICENSED UNDER CC BY-NC-SA 4.0
Comment