【webpack系列】从零搭建 webpack4+react 脚手架(四)

经过三个章节的学习,你已经学会搭建了一个基于webpack4的react脚手架。如果要更改配置,比如,你希望把编译后的js文件和css文件等单独放dist下的static目录下,你想想,是不是有点麻烦。你要去浏览webpack的配置文件,找到哪些配置项,然后去更改它,我们希望有个参数配置文件,只要更改参数配置,而无需更改webpack的配置文件。

1 添加参数配置文件

(1)在根目录创建config文件夹,在config文件夹内新建一个index.js文件,文件内容如下:
    ‘use strict‘

    const path = require(‘path‘)

    module.exports = {
        dev: {
            assetsSubDirectory: ‘static‘,
            assetsPublicPath: ‘/‘,
        },
        build: {
            assetsRoot: path.resolve(__dirname, ‘../dist‘),
            assetsSubDirectory: ‘static‘,
            assetsPublicPath: ‘/‘,
        }
    }

我们定义了一部分配置参数,顾名思义,dev属性下的参数配置是针对开发环境,build属性下的参数配置是针对生产环境的。其中,assetsRoot是编译后的文件存放根路径,assetsSubDirectory是资源文件编译后存放的文件夹名称,assetsPublicPath是公共的路径。

(2)修改webpack.base.conf.js,如下
    const path = require(‘path‘);
    const config=require(‘../config‘);
    const APP_PATH = path.resolve(__dirname, ‘../app‘);

    module.exports = {
        entry: {
            app: ‘./app/index.js‘,
            framework: [‘react‘, ‘react-dom‘],
        },
        output: {
            path: config.build.assetsRoot,
            filename: ‘[name].js‘,
            publicPath: process.env.NODE_ENV === ‘production‘
              ? config.build.assetsPublicPath
              : config.dev.assetsPublicPath
          },
        module: {
            rules: [
                {
                    test: /\.js?$/,
                    use: "babel-loader",
                    include: APP_PATH
                }
            ]
        }
    };

注意:我们在webpack.base.conf.js内配置了filename,那么dev环境下默认使用该配置,可以删除webpack.dev.conf.js内关于output的配置。

(3)路径生成方法:

路径的配置需要由assetsPublicPath和assetsSubDirectory以及具体的子路径组成,我们写一个公共的方法来生成路径。无论是开发环境还是生产环境,我们都可以复用该方法。我们在build文件夹下建立一个utils.js文件。内容如下:

    const path = require(‘path‘)
    const config = require(‘../config‘)

    exports.assetsPath = function (_path) {
        const assetsSubDirectory = process.env.NODE_ENV === ‘production‘
            ? config.build.assetsSubDirectory
            : config.dev.assetsSubDirectory

        return path.posix.join(assetsSubDirectory, _path)
    }
(4)修改webpack.prod.conf.js

在webpack.prod.conf.js页面头部引入

    const config=require(‘../config‘);
    const utils=require(‘./utils‘);

修改output属性的内容

     output: {
            path: config.build.assetsRoot,
            filename: utils.assetsPath(‘js/[name].[chunkhash:16].js‘),
            chunkFilename: utils.assetsPath(‘js/[id].[chunkhash].js‘)
        },

修改plugins内的相关配置:

    new CleanWebpackPlugin([config.build.assetsRoot], { allowExternal: true }),

    //导出css
    new MiniCssExtractPlugin({
        filename: utils.assetsPath(‘css/[name].[hash].css‘),
        chunkFilename: utils.assetsPath(‘css/[id].[hash].css‘),
    }),
(5)执行编译命令查看
npm run build

查看编译后的文件是否放在static目录下了。你可以修改参数配置文件,然后试试看吧。

2 更多的配置化

接下去我们会把更多的参数和变量进行配置化。

(1)index.html HTML模板的位置

在config.js文件的dev和build参数下都配置index属性:

index: path.resolve(__dirname, ‘../public/index.html‘),

修改HtmlWebpackPlugin内template的值:

webpack.prod.conf.js的相关修改:

     new HtmlWebpackPlugin({
                template: config.build.index,
                inject: ‘body‘,
                minify: {
                    removeComments: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true
                },
            }),

webpack.dev.conf.js的相关修改:

    new HtmlWebpackPlugin({
            template: config.dev.index,
            inject: true
    }),
(2)增加devServer 的配置

dev环境下,启动的端口号,代理相关,以及是否自动打开浏览器等等推荐可以放在参数配置文件内。

在config.js文件内增加相关配置参数:

    proxyTable: {},
    host: ‘localhost‘,
    port: 8080,
    autoOpenBrowser: true,

修改webpack.dev.conf.js内的相关配置:

     devServer: {
            host: config.dev.host,
            port: config.dev.port,
            contentBase: path.join(__dirname, ‘../public‘),
            compress: true,
            historyApiFallback: true,
            hot: true,
            https: false,
            noInfo: true,
            open: config.dev.autoOpenBrowser,
            proxy: config.dev.proxyTable,
    }

更多的css loader加载器

我们在loader中配置了less加载器,如果我们要支持其他呢,比如sass,scss等等,显然,我们需要在rules数组增加配置。其实,这里可以写成公共的生成方法。并且我们把部分参数变成可配置。比如:是否开启cssModule等。

(1)前期准备,增加部分参数配置

修改config.js内的配置:

    const path = require(‘path‘)

    module.exports = {
        base: {
            // 是否开启cssModule
            cssModule: true,
            // cssModule排除的目录, 其他css库可以放这里
            cssModuleExcludePath: /public/
        },
        dev: {
            assetsSubDirectory: ‘static‘,
            assetsPublicPath: ‘/‘,

            index: path.resolve(__dirname, ‘../public/index.html‘),

            proxyTable: {},

            host: ‘localhost‘,
            port: 8080,
            autoOpenBrowser: true,
            // 是否生成sourceMap
            cssSourceMap: true,

        },
        build: {
            assetsRoot: path.resolve(__dirname, ‘../dist‘),
            assetsSubDirectory: ‘static‘,
            assetsPublicPath: ‘/‘,

            index: path.resolve(__dirname, ‘../public/index.html‘),

            // 是否生成sourceMap
            productionSourceMap: true,
        }
    }
(2) 在utils.js内增加cssLoaders和styleLoaders方法:
    exports.cssLoaders = function (options) {
        options = options || {}

        let cssLoader = {
            loader: ‘css-loader‘,
            options: {
                importLoaders: 1,
                sourceMap: options.sourceMap
            }
        }
        if (options.cssModule) {
            cssLoader.options.modules = true;
            cssLoader.options.localIdentName = ‘[local]__[hash:7]‘;
        }
        const postcssLoader = {
            loader: ‘postcss-loader‘,
            options: {
                sourceMap: options.sourceMap
            }
        }
        function generateLoaders(loader, loaderOptions) {
            const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]

            if (loader) {
                loaders.push({
                    loader: loader + ‘-loader‘,
                    options: Object.assign({}, loaderOptions, {
                        sourceMap: options.sourceMap
                    })
                })
            }

            if (options.extract) {
                return [MiniCssExtractPlugin.loader].concat(loaders)
            } else {
                return [‘style-loader‘].concat(loaders)
            }
        }

        return {
            css: generateLoaders(),
            postcss: generateLoaders(),
            less: generateLoaders(‘less‘, { javascriptEnabled: true, indentedSyntax: true }),
            sass: generateLoaders(‘sass‘, { indentedSyntax: true }),
            scss: generateLoaders(‘sass‘),
            stylus: generateLoaders(‘stylus‘),
            styl: generateLoaders(‘stylus‘)
        }
    }

    exports.styleLoaders = function (options) {
        let output = []
        const loaders = exports.cssLoaders(options)
        for (const extension in loaders) {
            const loader = loaders[extension]
            let loaderObj = {
                test: new RegExp(‘\\.‘ + extension + ‘$‘),
                use: loader,
            }
            if (options.cssModule) {
                loaderObj.exclude = options.cssModuleExcludePath;
            }
            output.push(loaderObj)
        }

        if (options.cssModule) {
            options.cssModule = false
            const cssModuleLoaders = exports.cssLoaders(options)
            for (const extension in cssModuleLoaders) {
                const cssModuleLoader = cssModuleLoaders[extension]
                let cssModuleLoaderObj = {
                    test: new RegExp(‘\\.‘ + extension + ‘$‘),
                    use: cssModuleLoader,
                }
                cssModuleLoaderObj.include = options.cssModuleExcludePath;
                output.push(cssModuleLoaderObj)
            }
        }
        return output
    }
(3) 在webpack.prod.conf.js内使用

确认是否引入了utils,如果没有引入,在页面上方增加代码:

const utils=require(‘./utils‘);

修改 module内的rules属性:

    rules: utils.styleLoaders({
            sourceMap: config.build.productionSourceMap,
            extract: true,
            usePostCSS: true,
            cssModule:config.base.cssModule,
            cssModuleExcludePath:config.base.cssModuleExcludePath
    })

执行编译查看:

npm run build
(4) 在webpack.dev.conf.js内使用

确认是否引入了utils,如果没有引入,在页面上方增加代码:

const utils=require(‘./utils‘);

修改 module内的rules属性:

     rules: utils.styleLoaders({
            sourceMap: config.dev.cssSourceMap,
            usePostCSS: true,
            cssModule:config.base.cssModule,
            cssModuleExcludePath:config.base.cssModuleExcludePath
    })

执行dev命令试试看

npm run dev

下一节会对 如果对编译后的文件进行gzip压缩,如何让开发环境的控制台输出更加高逼格,如何更好的对编译后的文件进行bundle分析等问题展开讨论。

原文地址:https://www.cnblogs.com/nianzhilian/p/webpack.html

时间: 2024-11-09 10:41:08

【webpack系列】从零搭建 webpack4+react 脚手架(四)的相关文章

【webpack系列】从零搭建 webpack4+react 脚手架(二)

html文件如何也同步到dist目录?bundle.js文件修改了,万一被浏览器缓存了怎么办?如何为导出的文件加md5?如何把js引用自动添加到html?非业务代码和业务代码如何分开打包?如何搭建开发环境?如何实现开发环境的热更新? 在上一节我们已经搭建了一个最基本的webpack环境, 这一节我们带着上节的一些疑问,继续优化我们的react工程. 1.整合html-webpack-plugin public的index.html应该自动编译到dist目录,并且所有的js引用是自动添加的.你可以

【webpack系列】从零搭建 webpack4+react 脚手架(五)

本章节,我们一起来探讨以下问题:如何对编译后的文件进行gzip压缩,如何让开发环境的控制台输出更加高逼格,如何更好的对编译后的文件进行bundle分析等. 1 gzip压缩 如果你想节省带宽提高网站速度,压缩是一种简单有效的方法.我们模拟一次html的请求,想象一下浏览器和服务器的对话: 浏览器:嘿,给我来一个 index.html文件 服务器:好的,让我去找找它是不是在~ 服务器:找到它了,我会返回一个成功的状态码(200 ok),我正在发送文件-- 浏览器:100kb? 我滴天--等啊--等

React+Webpack+Webstorm开发环境搭建

需要安装的软件 node.js npm包管理 Webstorm 由于6.3.0版本之后会自带npm的包管理所以不需要单独的安装npm nodejs(包含npm)安装在默认路径C:\Program Files\nodejs比较好,也不是很大 Webstrom安装完成后,在打开的 License Activation 窗口中选择 License server. 在输入框输入网址:http://idea.iteblog.com/key.php 最后点击 Activate 构建项目和安装依赖包 使用we

OpenCV学习系列(零) Mac下OpenCV + xcode环境搭建

# OpenCV学习系列(零) Mac下OpenCV + xcode环境搭建 [-= 博客目录 =-] 1-学习目标 1.1-本章介绍 1.2-实践内容 1.3-相关说明 2-学习过程 2.1-homebrew安装 2.2-使用homebrew安装CMake 2.3-源码安装OpenCV 2.4-xcode配置与测试 2.5-基础问题回答 3-资料 1-学习目标 1.1-本章介绍 因为不可抗力(╯﹏╰),最近去图书馆借了一本<OpenCV编程案例详解>,准备学习OpenCV的使用,因为身患懒癌

react脚手架搭建1

23:01:17 react脚手架搭建 (个人用的是webstorm,所以分享下webstorm中的创建react脚手架项目的方法) 1.创建新项目(前提是下载nodejs环境) 2.下载好在webstorm中右键自己创建的项目目录,菜单中会出现一个命令行工具,点进去   然后    npm start 开启服务 3.在浏览器中打开 http://localhost:3000/ 可以看见react的默认页面 初步的搭建完成,开始自己写东西 原文地址:https://www.cnblogs.com

react脚手架搭建

react脚手架搭建 [转]https://blog.csdn.net/weixin_41421227/article/details/80875544 由于我们在安装的过程中要使用到npm  因此需要先前安装好node.js 直接到官方下载即可  一般建议大家下载稳定版的(左边那个!) 知道你们懒,咯官网戳→_→  node.js官网:https://nodejs.org/en/ 判断安装成功与否的标志↓ 打开cmd命令行,输入 node -v 和 npm -v 来查看版本号,如果显示则安装完

如何使用脚手架搭建一个react项目

1.准备工作: 首先要知道,搭建一个react项目总是需要安装node.js和npm的,未安装的请移步node.js官网:https://nodejs.org/en/ 检测是否安装成功:npm -v 和node -v 2.npm安装脚手架 执行命令npm install create-react-app 3.使用npx和脚手架创建项目my_app,这个过程可能需要几分钟,请耐心等待 npx create-react-app my_app 这里用到了npx,就是可以让你不用全局安装create-r

基于webpack和vue.js搭建开发环境

前言 在对着产品高举中指怒发心中之愤后,真正能够解决问题的是自身上的改变,有句话说的好:你虽然改变不了全世界,但是你有机会改变你自己.秉承着“不听老人言,吃亏在眼前”的优良作风,我还是决定玩火自焚. 问题所在 之前的项目总结为以下内容: 1.AMD模块规范开发,使用requirejs实现,使用rjs打包,最终导致的结果是,输出的项目臃肿,肿的就像一坨狗不理……不忍直视2.使用gulp进行打包,这一点貌似没有可吐槽的地方,毕竟都是被grunt折磨过来的……3.数据的渲染使用模板引擎,这就意味着你要

基于webpack和vue.js搭建的H5端框架(其实主要用于Hybrid开发H5端框架,但是依然能够作为纯web端使用)

人类的发展得益于对追求不断的提升,在能活着的基础上是否要活得潇洒一点,技术的发展亦如是.在公司作为一个最最最最最最最底层的搬砖码农,经历了两个版本的铸(zhe)炼(mo)之后,我痛下决心今后一定要:…………..一定要和产品惺(shi)惺(bu)相(liang)惜(li). 开始之前 本文包含以下技术,文中尽量给与详细的描述,并且附上参考链接,读者可以深入学习: 1.webpack2.Vue.js3.npm4.nodejs —- 这个就不给连接了,因为上面的连接都是在你实践的过程中要去不断访问的5