分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

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

发布时间:2023-09-06 02:29责任编辑:赖小花关键词:webpack

经过三个章节的学习,你已经学会搭建了一个基于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分析等问题展开讨论。

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

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

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved