Reputation: 4217
I'm using Laravel Mix, and it nicely simplifies using WebPack & Babel to transpile advance JS features down to older browsers - EXCEPT! (and I'm going crazy here) ... it only works for me if I put the JS to be transpiled into the directory they recommend.
The basic recommended "webpack.mix.js" setup is mix.js(['resources/js/app.js'], 'public/js/app.js');
where the first argument can be a single file or an array of files to be transpiled.
The default resources/js/app.js
requires several standard modules, like vue, lodash, axios. Works great. Then in app.js
I want to require some additional sources from vendor/xxxx/assets/js/xx.js
- but I get an error: Unknown plugin "transform-object-rest-spread" specified
- which means it can't find the babel plugin, which is definitely installed. It's something with the path.
If I copy that xx.js
into the resources/js
and then require it in app.js
, no problem.
I've used mix.webpackConfig
to add the module path vendor/xxxx/assets/js
, I've used alisas to set 'xx$': path.resolve(__dirname,"vendor/xxxx/assets/js/xx.js"
, and tried to mess around with the babel options, both in .babelrc & the webpackConfig option object.
The one version of the final webpack config is below - believe me, I've played with many variants, I know this isn't the one right one, but nothing has worked to import/require/transpile any file outside of either node_modules (vue) or /resources/js (app.js, which can also require other files within that directory). Any ideas would be great!
{ context: 'C:\\www\\Laravels\\lsbb-5-3\\laravel',
entry:
{ '/mixed/js/es6':
[ 'C:\\www\\Laravels\\lsbb-5-3\\laravel\\resources\\js\\app.js',
'C:\\www\\Laravels\\lsbb-5-3\\laravel\\vendor\\xxxx\\js\\xx.js' ] },
output:
{ path: 'C:\\www\\Laravels\\lsbb-5-3\\laravel\\public',
filename: '[name].js',
chunkFilename: '[name].js',
publicPath: '/' },
module:
{ rules:
[ { test: /\.html$/, loaders: [ 'html-loader' ] },
{ test: /(\.(png|jpe?g|gif)$|^((?!font).)*\.svg$)/,
loaders:
[ { loader: 'file-loader',
options: { name: [Function: name], publicPath: '/' } },
{ loader: 'img-loader',
options: { enabled: true, gifsicle: {}, mozjpeg: {}, optipng: {}, svgo: {} } } ] },
{ test: /(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/,
loader: 'file-loader',
options: { name: [Function: name], publicPath: '/' } },
{ test: /\.(cur|ani)$/,
loader: 'file-loader',
options: { name: '[name].[ext]?[hash]', publicPath: '/' } },
{ test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use:
[ { loader: 'babel-loader',
options:
{ cacheDirectory: true,
presets:
[ [ 'env',
{ modules: false,
targets: { browsers: [ '> 2%' ], uglify: true } } ] ],
plugins:
[ 'transform-object-rest-spread',
[ 'transform-runtime', { polyfill: false, helpers: false } ],
[ 'transform-object-rest-spread' ] ] } } ] },
{ test: /\.css$/, loaders: [ 'style-loader', 'css-loader' ] },
{ test: /\.s[ac]ss$/,
exclude: [],
loaders: [ 'style-loader', 'css-loader', 'sass-loader' ] },
{ test: /\.less$/,
exclude: [],
loaders: [ 'style-loader', 'css-loader', 'less-loader' ] } ] },
plugins:
[ FriendlyErrorsWebpackPlugin {
compilationSuccessInfo: {},
onErrors: undefined,
shouldClearConsole: true,
formatters: [ [Function: format], [Function: format], [Function: format] ],
transformers:
[ [Function: transform],
[Function: transform],
[Function: transform] ] },
DefinePlugin {
definitions: { 'process.env': { NODE_ENV: '"development"' } } },
LoaderOptionsPlugin {
options:
{ minimize: false,
options:
{ context: 'C:\\www\\Laravels\\lsbb-5-3\\laravel\\node_modules\\laravel-mix\\src\\builder',
output: { path: './' } },
test: { test: [Function: test] } } },
ManifestPlugin {},
CustomTasksPlugin {},
BuildCallbackPlugin { callback: [Function] },
{ options:
{ title: 'Laravel Mix',
alwaysNotify: true,
hint: undefined,
contentImage: 'C:\\www\\Laravels\\lsbb-5-3\\laravel\\node_modules\\laravel-mix\\icons\\laravel.png' },
lastBuildSucceeded: false,
isFirstBuild: true } ],
stats:
{ hash: false,
version: false,
timings: false,
children: false,
errorDetails: false,
chunks: false,
modules: false,
reasons: false,
source: false,
publicPath: false },
performance: { hints: false },
devtool: 'eval-source-map',
devServer:
{ headers: { 'Access-Control-Allow-Origin': '*' },
contentBase: 'C:\\www\\Laravels\\lsbb-5-3\\laravel\\public',
historyApiFallback: true,
noInfo: true,
compress: true,
quiet: true },
resolve:
{ extensions: [ '*', '.js', '.jsx', '.vue' ],
alias:
{ 'vue$': 'vue/dist/vue.common.js',
'xx$': 'vendor/xxxx/js/xx.js',
modules:
[ 'node_modules',
'vendor/xxxx/js' ] } }
Upvotes: 0
Views: 1140
Reputation: 1645
The solution as found over on Github is to add this to your mix file:
mix.webpackConfig({ resolve: { symlinks: false } })
🙌
Upvotes: 0
Reputation: 4217
AHH! After days & nights, I finally figured it out! The files in question are kind of like a library that I use in several projects, so I just symlink the directory into the project. I've been doing that for YEARS without problems with all kinds of build & project tools, so I didn't give it a thought.
BUT it turns out that Babel (or Babel in WebPack) breaks when it tries to follow symlinks!
So I can't say I found a solution, but I found a suitable work-around. The first step of my build process I just copy the files from the source directory into the project directory. Thats disgusting but actually works fine for my purposes - which is to just edit the library in a single location so I don't wind up with different versions. So I can just edit the source & build & voila!
If you have this problem and want to do it right, there are supposed to be additional plugins that help babel resolve these path issues but once I figured out what the problem was, I couldn't be bothered. Good luck to anyone else!
Upvotes: 1