remove absulte path from webpack output - reactjs

Well, I build my app using webpack in production mode, I have the output files containing absolute paths like :
E:/xxxx/xxxx/src/app/core/components/lib/RadioButtonGroupEntry.js
This is my webpack configuration:
resolve: {
//When require, do not have to add these extensions to file's name
extensions: ["", ".js", ".jsx"],
},
//Render source-map file for final build
//output config
output: {
path: buildPath, //Path of output file
filename: '[name]-[chunkhash].js', //Name of output file
publicPath: '/'
},
node: {
fs: 'empty'
},
plugins: [
//Minify the bundle
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
//supresses warnings, usually from module minification
warnings: false
}
}),
//Allows error warnings but does not stop compiling. Will remove when eslint is added
new webpack.NoErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: Infinity,
}),
// new InlineManifestWebpackPlugin({
// name: 'webpackManifest'
// }),
new WebpackMd5Hash(),
// new ManifestPlugin(),
// new ChunkManifestPlugin({
// filename: "chunk-manifest.json",
// manifestVariable: "webpackManifest"
// }),
new HtmlWebpackPlugin({template: 'src/www/index.ejs'}),
//Transfer Files
new TransferWebpackPlugin([{from: 'www'}], path.resolve(__dirname,'src'))]
I think my webpack.config is messed up and I would like some help to figure out what is wrong with it so that the absolute path will be removed.
Thanks.

Maybe you could try to configure the output path property of your webpack configuration object with path and the node __dirname global object, as this:
output: {
path: path.resolve(__dirname, 'yourBuildFolder')
}

I had a similar issue (I use multiple entries) and solved it with path.relative():
{
entry: {
'head': [
`./${path.relative(__dirname, 'my/source/path.js')}`,
...
]
},
...
}

Related

I can't find the vender.js when I use webpack

I am using webpack and having a problem.I want to product a html in the public but I can't succeed.
when I use npm run dev ,I encounter a problem
this is my github
https://github.com/wohuifude123/webpack20180315
supplement
I have read you answer many times, and then I modidy webpack.dll.js
output: {
path: __dirname + 'public/dist',
filename: '[name].[chunkhash:8].js',
library: '[name]_[chunkhash:8]'
},
and then I modify the webpack.dev.js
const path = require('path');
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
// 引入dev-server配置文件
let BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
// a third party
const manifest = require('./vender-manifest.json');
const _venderName = manifest.name.split('_');
const venderName = _venderName[0] + '.' + _venderName[1];
module.exports = merge(common, {
output: { //打包路径
//filename: '[name].bundle.js', //出口文件名
// filename: '[name].[chunkhash].js',
// 可以使用__dirname变量获取当前模块文件所在目录的完整绝对路径
path: __dirname + 'dist', //打包路径
publicPath:'dist/', // 指定publicPath
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js',
library: '[venderName].js'
},
devtool: 'source-map',
devServer: {
contentBase: [path.join(__dirname, "./public")], // 本地服务器 加载页面 所在的目录
host: '127.0.0.1',
compress: true,
port: 6600,
open: false // 将自动打开浏览器
},
plugins:[
new BundleAnalyzerPlugin({
analyzerMode: 'server', // static/disabled
analyzerHost: '127.0.0.1',
analyzerPort: 9900,
openAnalyzer: false
})
]
});
finally I modify the webpack.common.js
plugins: [
new CleanWebpackPlugin(['dist'], { // 清除 dist 文件中的内容
exclude: [venderName + '.js'] // 排除 提取出的 第三方的 js
}),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./vender-manifest.json') // 加载 manifest.json
}),
new HtmlWebpackPlugin({
filename: './index.html',
template: './src/index.html',
//favicon: './src/favicon.ico',
alwaysWriteToDisk: true // 是否开启 new HtmlWebpackHarddiskPlugin()
}),
new HtmlWebpackIncludeAssetsPlugin({
assets: [venderName + '.js'],
append: false // 不会被 webpack 自动打包
}),
// new HtmlWebpackIncludeAssetsPlugin({
// assets: ['config/env-config.js'],
// append: false, // 不会被 webpack 自动打包
// hash: true
// }),
new HtmlWebpackHarddiskPlugin(), // 将[venderName + '.js']和['env-config.js']放进 index.html 中
new webpack.DefinePlugin({ // 创建一个编译时可以配置的全局常量
PRODUCTION: JSON.stringify(true),
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
})
]
Although I have read your answer carefully, I can't understand details.
I try to modify many places ,but the product can't work .
There are 2 problems in your code:
You are not matching the dll library to your app's output library:
Your webpack.dll.js:
output: {
// some properties
library: '[name]_[chunkhash:8]'
}
//...
new webpack.DllPlugin({
name: '[name]_[chunkhash:8]'
})
Your webpack.dev.js:
const manifest = require('./vender-manifest.json');
//...
module.exports = merge(common, {
output: {
// some properties
library: manifest.name // this was missing
}
}
What I see you were doing was matching the DllPlugin name to the dll output file library, which is not the case.
The webpack dll plugin docs inform to Keep the name consistent with output.library, but applying to where you are using the dll (while using DllReferencePlugin), not where you are creating them (DllPlugin).
You are not creating the dll in the dist folder:
Your webpack dll config looks like:
output: {
path: __dirname + '/dist'
}
which writes your dll file into rootDir/dist and not rootDir/public/dist as you rather wanted.
So the fix for this one would be to just change it to path: __dirname + 'public/dist'.
After those fixes your code started to work for me. If you have any more questions feel free to ask ;)

webpack DefinePlugin use external config.js

I am new in webpack
I have this code in webpack.config.js
var path = require('path');
var webpack = require('webpack');
var pkg = require('./package.json');
var myconfig = require('./webpack.myconfig.js');
// bundle dependencies in separate vendor bundle
var dependencies = Object.keys(pkg.dependencies).filter(function (el) {
//exclude font packages from vendor bundle & css-toggle-switch
if (el.indexOf('font') !== -1 || el.indexOf('css-toggle-switch') !== -1) {
return false;
}
else return true;
});
module.exports = {
entry: {
libs: dependencies,
main: './src/index'
},
output: {
path: path.join(__dirname, myconfig.buildPath),
publicPath: myconfig.uiURL,
filename: 'dist/js/[name].js',
chunkFilename: '[id].[name].js'
},
plugins: [
new webpack.DefinePlugin({
DEBUG_MODE: JSON.stringify(false),
TIMEOUT: JSON.stringify(30000),
API_URL: JSON.stringify(myconfig.apiUrl),
"process.env": {
NODE_ENV: JSON.stringify("production")
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'libs',
filename: 'dist/js/libs.js',
minChunks: Infinity
})
],
};
and this is myconfig.js
myconfig = {
uiURL: 'http://example.com/',
apiUrl: 'http://api.example.com/api/'
};
module.exports = myconfig;
and if I run this syntax
webpack -p --config webpack.config.js --progress --colors
I will get the result like
/dist/js/libs.js
/dist/js/main.js
but I want the result not like this, I want the result to be:
/dist/js/myconfig.js
/dist/js/libs.js
/dist/js/main.js
What really I want is,
I want in main.js file, it will use myconfig.apiUrl as depedencies,
so when I deployed to production or qserver, I just change myconfig.js.
Thank you
webpack.myconfig.js is used in webpack config file so you have to rebuild every time when webpack.myconfig.js is changed.
You could use myconfig.json and send http request to get it dynamically.
If you just want to get myconfig.js in /dist/js/, you can use CopyWebpackPlugin. It can copy static files from one path to another.
Add a new new line plugins section like :
plugins: [
new CopyWebpackPlugin([{ from: APP_DIR + '\\images', to: APP_DIR + '\\build\\images' }]),
new webpack.DefinePlugin({
DEBUG_MODE: JSON.stringify(false),
TIMEOUT: JSON.stringify(30000),
API_URL: JSON.stringify(myconfig.apiUrl),
"process.env": {
NODE_ENV: JSON.stringify("production")
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'libs',
filename: 'dist/js/libs.js',
minChunks: Infinity
})
],
Here CopyWebpackPlugin copies file from one path to another.
Make sure you var CopyWebpackPlugin = require('copy-webpack-plugin');at top of webpack.config.js & added same in package.json & installed via npm.

Webpack - react works even when it's not in 'vendors'

I'm working with Webpack+React and I'm using the CommonsChunkPlugin. The thing is that react works even when I don't put it in the 'vendors' entry (same for other packages). Does that make sense?
My config looks like this:
config.entry.vendors = ['mobx', 'jquery', 'highcharts', 'react-highcharts', 'moment', 'numeral', 'jquery-ui', 'jquery.cookie', 'lodash', 'jquery.waitforimages', 'raven-js'];
config.module.loaders = config.module.loaders.concat([
{
test : /\.less$/,
loader: ExtractTextPlugin.extract({
fallback: "style-loader",
loader : "css-loader?sourceMap!postcss-loader!less-loader?sourceMap"
})
}
]);
config.plugins = config.plugins.concat([
new ExtractTextPlugin('[name]-[chunkhash].min.css'),
new webpack.optimize.UglifyJsPlugin({
minimize : true,
mangle : false, // { except: ['$super', '$', 'exports', 'require'] },
compressor: {
warnings : false,
screw_ie8: true
},
sourceMap : true
}),
new StatsPlugin('webpack.stats.json', {
source : false,
modules: false
}),
new webpack.optimize.CommonsChunkPlugin({name: 'vendors', filename: 'vendors-[chunkhash].min.js'}),
new WebpackMd5Hash(),
new ManifestPlugin(),
new InlineManifestWebpackPlugin({
name: 'webpackManifest'
})
]);
The output value of webpack is:
output: {
filename : '[name].bundle.js',
publicPath : '/',
path : paths.dist,
sourceMapFilename: "[name].js.map",
},
CommonsChunkPlugin is smart enough, you didn't specify chunks property for CommonsChunkPlugin, that means that plugin will try to go through all your entries and move common parts to vendors chunk and then into vendors-[chunkhash].min.js file.
e.g. you have 2 entry points: index.js, signin.js and in both you have next code:
const React = require('react')
const ReactDOM = require('react-dom')
So with configuration like
entry: {
app: './index.js',
signin: './signin.js',
vendor: ['react']
},
*****
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor-[chunkhash].js'
})
]
you will still have react-dom in vendor chunk.
On another hand if you have third entry point without requiring react-dom, only react will be moved to vendor chunk.
But even in this case you will still have react-dom included into first two entry chunks.
The thing is that react works event when I don't put it in the 'vendors' entry (same for other packages).
So react will work in any case, the only difference will be, will react chunk be moved to vendors or not, if not, it still will be included in your entry point file.
Hope it helps.

Webpack2 can't resolve file in pathname

I have having a strange issue I can't seem to resolve.
I am getting this error:
Error: Can't resolve 'store/configureStore' in '/Users/samboy/company/oh-frontend/app'
My webpack file looks like this:
name: 'browser',
context: path.join(__dirname, '..', '..', '..', 'app'),
entry: {
app: './client'
},
output: {
// The output directory as absolute path
path: assetsPath,
// The filename of the entry chunk as relative path inside the output.path directory
filename: '[name].js',
// The output path from the view of the Javascript
publicPath: publicPath
},
module: {
loaders: commonLoaders
},
resolve: {
modules: [
path.resolve(__dirname, '..', '..', '..', 'app'),
'node_modules'
],
extensions: ['', '.js', '.jsx', '.css']
},
plugins: [
// extract inline css from modules into separate files
new ExtractTextPlugin('styles/bundled-modules.css'),
// files in global directory should be concatenated into one file for prod
new CopyWebpackPlugin([
{ from: 'fonts/', to: 'fonts/' }
, { from: '_web/css/global/fonts.css', to: 'styles/fonts.css' }
, { from: '_web/css/vendors', to: 'styles/vendors' }
]),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
}),
new webpack.DefinePlugin({
__DEVCLIENT__: false,
__DEVSERVER__: false,
__PLATFORM_WEB__: true,
__PLATFORM_IOS__: false
}),
new InlineEnviromentVariablesPlugin({ NODE_ENV: 'production' }),function()
{
this.plugin("done", function(stats)
{
if (stats.compilation.errors && stats.compilation.errors.length)
{
console.log(stats.compilation.errors);
process.exit(1);
}
// ...
});
}
],
postcss: postCSSConfig
}
The file is certainly present in that folder. It worked fine with webpack. It doesn't seem to work with webpack2 though.
I'm guessing because you didn't post your app file, but can you change the import statement in the app file to "./store/configureStore"?

react with webpack gives me a massive bundle.js file

Ok I have read many posts(like this one) on here about optimizing bundle.js for a production build but they are not changing my bundle.js file at all so I must be doing something wrong. I am building with the command:
webpack -p --config webpack.production.config.js
and webpack.production.config.js looks like this:
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'inline-source-map',
entry: [
'./src/index.js'
],
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js'
},
resolve: {
modulesDirectories: ['node_modules', 'src'],
extensions: ['', '.js']
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot', 'babel?presets[]=react,presets[]=es2015']
}
]
},
alias: {
'react$': path.join(__dirname, 'node_modules', 'react','dist','react.min.js'),
'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist','react-dom.min.js')
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
})
],
};
I am at a loss. I have 17 node_modules including all the basics like react and webpack. My bundle.js file is 15.6MB....absolutely massive and unacceptable. From what I am reading it looks like the -p and this plug in
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
})
should automatically use the .min.js version of everything. Is that correct? Do I have to do anything to force my application to use that?
Any optimization would help tremendously! The application is not really that large and the initial load of the page is taking WAY to long.
Thanks!!
For a production build try changing devtool: 'inline-source-map' to devtool: 'source-map'
The webpack config from https://webpack.github.io/docs/configuration.html says:
inline-source-map - A SourceMap is added as DataUrl to the JavaScript
file.
Also, and again for production builds, you can remove 'react-hot' in the loaders section.
For example, with these differences in one of my projects the development bundle is 9MB but the production one is 600KB. Hopefully you'll see similar improvements.
I highly recommend you read this tutorial,the answer is very obvious after reading this.
Put simply ,you can use a plugin named uglify which can reduce the bundle size dramatically.
In addition, 'NODE_ENV': JSON.stringify('production') is used by React ,nothing to do with webpack

Resources