经过三个章节的学习,你已经学会搭建了一个基于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.assetsSubDirectoryreturn 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: {// 是否开启cssModulecssModule: true,// cssModule排除的目录, 其他css库可以放这里cssModuleExcludePath: /public/},dev: {assetsSubDirectory: 'static',assetsPublicPath: '/',index: path.resolve(__dirname, '../public/index.html'),proxyTable: {},host: 'localhost',port: 8080,autoOpenBrowser: true,// 是否生成sourceMapcssSourceMap: true,},build: {assetsRoot: path.resolve(__dirname, '../dist'),assetsSubDirectory: 'static',assetsPublicPath: '/',index: path.resolve(__dirname, '../public/index.html'),// 是否生成sourceMapproductionSourceMap: 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 = falseconst 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

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

  1. 从零搭建 webpack4+react 脚手架

    前提条件 在开始之前,请确保安装了 Node.js 的最新版本.建议使用 Node.js 最新的长期支持版本(LTS - Long Term Support).如果你使用旧版本,你可能遇到各种问题,因 ...

  2. springboot项目结构_从零搭建Spring Boot脚手架(1):开篇以及技术选型

    1. 前言 目前Spring Boot已经成为主流的Java Web开发框架,熟练掌握Spring Boot并能够根据业务来定制Spring Boot成为一个Java开发者的必备技巧,但是总是零零碎碎 ...

  3. 从零搭建Spring Boot脚手架(2):增加通用的功能

    1. 前言 上一篇说了我要一步步地搭建Spring Boot脚手架,首先会集成Spring MVC并进行定制化以满足日常开发的需要,我们先做一些刚性的需求定制,后续再补充细节.如果你看了本文有什么问题 ...

  4. 从零搭建Spring Boot脚手架(4):手写Mybatis通用Mapper

    1. 前言 今天继续搭建我们的kono Spring Boot脚手架,上一文把国内最流行的ORM框架Mybatis也集成了进去.但是很多时候我们希望有一些开箱即用的通用Mapper来简化我们的开发.我 ...

  5. 从零搭建Spring Boot脚手架(2):增加通用的功能(转载)

    前言 上一篇说了我要一步步地搭建Spring Boot脚手架,首先会集成Spring MVC并进行定制化以满足日常开发的需要,我们先做一些刚性的需求定制,后续再补充细节.如果你看了本文有什么问题可以留 ...

  6. 从零搭建Spring Boot脚手架:开篇以及技术选型1

    1. 前言 目前Spring Boot已经成为主流的Java Web开发框架,熟练掌握Spring Boot并能够根据业务来定制Spring Boot成为一个Java开发者的必备技巧,但是总是零零碎碎 ...

  7. 【停车场车辆管理系统】从零搭建——前端react搭建

    [停车场车辆管理系统]从零搭建--项目分析 [停车场车辆管理系统]从零搭建--数据库搭建 [停车场车辆管理系统]从零搭建--后端搭建 [停车场车辆管理系统]从零搭建--后端Model类 [停车场车辆管 ...

  8. React 开发环境的搭建 (React脚手架)

    1. react脚手架 xxx脚手架: 用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需要的配置(语法检查.jsx编译.devServer-) 下载好了所有相关的依赖 可以直接运行一个简 ...

  9. React入门:从零搭建一个React项目

    一.初始化项目 新建文件夹,文件名firstreact 文件夹名称不要用react,node这类关键字,后面使用插件时会发生错误. init项目环境,项目信息可默认或自行修改 mkdir firstr ...

最新文章

  1. .gitignore和.gitkeep有什么区别?
  2. 1.9 可避免误差-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授
  3. 在Python中使用一个元素创建一个元组
  4. Z-Stack Home Developer's Guide—8. Additional Information for HA Applications中文翻译
  5. leetcode - Interleaving String
  6. vscode 插件使用(前端力推)
  7. php使用常量cont,php常量介绍
  8. java8 追加文字到文件_使用Stream-Java 8替换文件中的文本
  9. [UI]实用案例--Shape绘制实用圆圈
  10. [python + debug] set()操作对象的元素为字符串,则结果随机排序,使用sorted()函数以固定顺序
  11. 在python中使用sort_详解python中sort排序使用
  12. 第三方支付接口有哪些?怎么申请?
  13. 推荐一款云服务器免费试用,可以延期再使用
  14. GB28181协议视频流媒体平台中国标设备编号和通道国标编号标记唯一的摄像头|视频|镜头通道
  15. Android12 HDR相关
  16. ZooKeeper客户端源码(三)——Watcher注册与通知
  17. 一行代码教你撩妹手到擒来html+css+js烟花告白3D相册(含音乐+可自定义文字)520表白/七夕情人节/求婚...
  18. 大数据_Hive_Hsql
  19. 为了网络安全被束缚的无人机背后的故事!
  20. cv岗工作做什么_2019 秋招 cv 岗求职心得

热门文章

  1. 暂停交易?ERC20合约整数溢出安全漏洞案例技术分析一
  2. nginx日志查看goaccess安装使用
  3. 图片插入mysql数据库_图片如何存入数据库?
  4. python自动加载配置文件中模块名_python----读取配置文件(configparser模块)
  5. 设计模式002:简单工厂模式
  6. java中nodelist的用法_我可以在Java中使用for-each遍历一个NodeList吗?
  7. 中除了某个数以外的_除了奇异博士以外漫威中九位超强法师,第四位活了一万七千年...
  8. java生产订单号_java 生成订单号
  9. mysql 创建分区索引吗_MySQL分区字段列有必要再单独建索引吗?
  10. 基于参考点的非支配遗传算法-NSGA-III(二)