Dom*_*nic 81 javascript conditional build require webpack
我有一些需要开发的东西 - 例如我想不会破坏我的分布式构建文件的模拟.
在RequireJS中,您可以在插件文件中传递配置,并根据需要调整其中的内容.
对于webpack,似乎没有办法做到这一点.首先创建一个环境中运行时配置我用resolve.alias重新指向一个取决于环境,例如,需要:
// All settings.
var all = {
fish: 'salmon'
};
// `envsettings` is an alias resolved at build time.
module.exports = Object.assign(all, require('envsettings'));
Run Code Online (Sandbox Code Playgroud)
然后在创建webpack配置时,我可以动态分配哪些文件envsettings
指向(即webpackConfig.resolve.alias.envsettings = './' + env
).
不过我想做的事情如下:
if (settings.mock) {
// Short-circuit ajax calls.
// Require in all the mock modules.
}
Run Code Online (Sandbox Code Playgroud)
但显然我不想在环境不是模拟的情况下构建那些模拟文件.
我可以再次使用resolve.alias手动将所有这些需求重新命名为存根文件 - 但是有没有一种感觉不那么hacky的方法?
我有什么想法可以做到这一点?谢谢.
Mat*_*ick 58
您可以使用define插件.
我通过在webpack构建文件中执行一些简单的操作来使用它,其中env
是导出设置对象的文件的路径:
// Webpack build config
plugins: [
new webpack.DefinePlugin({
ENV: require(path.join(__dirname, './path-to-env-files/', env))
})
]
// Settings file located at `path-to-env-files/dev.js`
module.exports = { debug: true };
Run Code Online (Sandbox Code Playgroud)
然后在你的代码中
if (ENV.debug) {
console.log('Yo!');
}
Run Code Online (Sandbox Code Playgroud)
如果条件为false,它将从构建文件中删除此代码.您可以在此处查看有效的Webpack构建示例.
nml*_*nml 34
不知道为什么"webpack.DefinePlugin"答案是定义基于环境的导入/需求的最顶层的答案.
这种方法的问题在于您仍然将所有这些模块交付给客户端 - > 例如,使用webpack-bundle-analyezer进行检查.并没有减少你的bundle.js的大小:)
那么真正运作良好且更符合逻辑的是:NormalModuleReplacementPlugin
因此,而不是做一个on_client条件要求 - >首先不要包含不需要的文件到bundle
希望有所帮助
Bry*_*man 27
使用ifdef-loader
.在您的源文件中,您可以执行类似的操作
/// #if ENV === 'production'
console.log('production!');
/// #endif
Run Code Online (Sandbox Code Playgroud)
相关webpack
配置是
const preprocessor = {
ENV: process.env.NODE_ENV || 'development',
};
const ifdef_query = require('querystring').encode({ json: JSON.stringify(preprocessor) });
const config = {
// ...
module: {
rules: [
// ...
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: `ifdef-loader?${ifdef_query}`,
},
},
],
},
// ...
};
Run Code Online (Sandbox Code Playgroud)
ofh*_*use 21
我最终使用类似于Matt Derrick'Answer的东西,但担心两点:
ENV
(这对于大型配置是不好的).require(env)
指向不同的文件.我想出的是一个简单的作曲家,它构建一个配置对象并将其注入配置模块.
这是文件结构,Iam用于此:
config/
??? main.js
??? dev.js
??? production.js
src/
??? app.js
??? config.js
??? ...
webpack.config.js
Run Code Online (Sandbox Code Playgroud)
在main.js
拥有所有默认配置的东西:
// main.js
const mainConfig = {
apiEndPoint: 'https://api.example.com',
...
}
module.exports = mainConfig;
Run Code Online (Sandbox Code Playgroud)
在dev.js
与production.js
仅持有它覆盖的主要配置配置的东西:
// dev.js
const devConfig = {
apiEndPoint: 'http://localhost:4000'
}
module.exports = devConfig;
Run Code Online (Sandbox Code Playgroud)
重要的部分是webpack.config.js
组成配置并使用DefinePlugin生成一个环境变量__APP_CONFIG__
来保存组合的配置对象:
const argv = require('yargs').argv;
const _ = require('lodash');
const webpack = require('webpack');
// Import all app configs
const appConfig = require('./config/main');
const appConfigDev = require('./config/dev');
const appConfigProduction = require('./config/production');
const ENV = argv.env || 'dev';
function composeConfig(env) {
if (env === 'dev') {
return _.merge({}, appConfig, appConfigDev);
}
if (env === 'production') {
return _.merge({}, appConfig, appConfigProduction);
}
}
// Webpack config object
module.exports = {
entry: './src/app.js',
...
plugins: [
new webpack.DefinePlugin({
__APP_CONFIG__: JSON.stringify(composeConfig(ENV))
})
]
};
Run Code Online (Sandbox Code Playgroud)
现在的最后一步是config.js
,它看起来像这样(在这里使用es6 import export语法,因为它在webpack下):
const config = __APP_CONFIG__;
export default config;
Run Code Online (Sandbox Code Playgroud)
在你的app.js
,你现在可以使用import config from './config';
获得的配置对象.
Ale*_*lva 18
另一种方法是使用JS文件作为proxy
,并让该文件加载感兴趣的模块commonjs
,并将其导出为es2015 module
,如下所示:
// file: myModule.dev.js
module.exports = "this is in dev"
// file: myModule.prod.js
module.exports = "this is in prod"
// file: myModule.js
let loadedModule
if(WEBPACK_IS_DEVELOPMENT){
loadedModule = require('./myModule.dev.js')
}else{
loadedModule = require('./myModule.prod.js')
}
export const myString = loadedModule
Run Code Online (Sandbox Code Playgroud)
然后您可以在您的应用中正常使用ES2015模块:
// myApp.js
import { myString } from './store/myModule.js'
myString // <- "this is in dev"
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
61273 次 |
最近记录: |