Laravel mix extract function not found - node.js

I have a pretty standard webpack file for my laravel app
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.extract("['lodash', 'axios', 'jquery','bootstrap','tether','prismjs','jquery.mb.ytplayer','owl.carousel']")
.sass('resources/sass/app.scss', 'public/css')
.sourceMaps();
if (mix.inProduction()) {
mix.version();
}
But npm run watch fails with following error
anadi#MacAnadi onex_web % npm run watch
> # watch /Users/anadi/Code/github/onex/website/onex_web
> npm run development -- --watch
> # development /Users/anadi/Code/github/onex/website/onex_web
> cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js "--watch"
/Users/anadi/Code/github/onex/website/onex_web/node_modules/webpack-cli/bin/cli.js:93
throw err;
^
TypeError: extraction.libs.join is not a function

You've passed your arguments as string to the extract method. It takes an array and since join is not a function in String.prototype, this is what causes a TypeError. Changing your call into below will work.
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.extract(['lodash', 'axios', 'jquery','bootstrap','tether','prismjs','jquery.mb.ytplayer','owl.carousel'])
.sass('resources/sass/app.scss', 'public/css')
.sourceMaps();
if (mix.inProduction()) {
mix.version();
}

Related

My React App Unit Tests Jest is breaking: function(module,exports,require,__dirname,__filename,jest) Cannot use import statement outside a module

I'm facing a problem when trying to run the Jest tests (NextJs app) with my component library.
My React library
I'm using this command to build the React library:
"build-esm": "tsc --project tsconfig.build.json",
"build-cjs": "tsc --project tsconfig.build.json --module commonjs --outDir lib/cjs",
"build": "rm -fr lib/ && npm run build-esm && npm run build-cjs"
Will generate it:
package.json:
(...)
"main": "./lib/cjs/index.js",
"module": "./lib/esm/index.js",
"types": "./lib/esm/index.d.ts",
(...)
My "Nextjs client project" (that will use the lib as a dependency):
jest.config.js
// jest.config.js
const nextJest = require('next/jest');
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './'
});
// Add any custom config to be passed to Jest
/** #type {import('jest').Config} */
const customJestConfig = {
// Add more setup options before each test is run
setupFilesAfterEnv: ['./jest.setup.js'],
// if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
moduleDirectories: ['node_modules'],
testEnvironment: 'jest-environment-jsdom',
transformIgnorePatterns: ['<rootDir>/node_modules/']
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
console error:
(...)/node_modules/nanoid/index.browser.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { urlAlphabet } from './url-alphabet/index.js'
^^^^^^
SyntaxError: Cannot use import statement outside a module
8 | var react_window_1 = require("react-window");
9 | var react_window_infinite_loader_1 = __importDefault(require("react-window-infinite-loader"));
> 10 | var nanoid_1 = require("nanoid");
I appreciate any support

Load .env environment variables when running npm task

Let's say we have a .env file with some variables specified:
AWS_PROFILE=hsz
ENVIRONMENT=development
There is also a simple npm task defined:
{
"name": "project",
"version": "0.0.1",
"scripts": {
"deploy": "sls deploy"
}
}
But runnning npm run deploy ignores our .env definition.
It can be resolved with better-npm-run like:
{
"name": "project",
"version": "0.0.2",
"scripts": {
"deploy": "bnr deploy"
},
"betterScripts": {
"deploy": "sls deploy"
},
"devDependencies": {
"better-npm-run": "^0.1.1",
}
}
but this looks like an overhead - especially when we have 10+ tasks.
Is there a better way to always load .env without proxying all tasks via better-npm-run?
A bit ugly, but you could try something like this:
"scripts": {
"deploy": "export $(cat .env | xargs) && sls deploy"
}
This will export all environment variables from the .env file before running sls deploy.
There are some variations to this tehnique in this answer.
Not very clean but it avoids usage of an extra module.
You can use env-cmd npm package to set environment variables loaded from .env file before executing a npm script.
Add package to your package.json devDependencies:
npm i env-cmd -D
Prefix your npm script with env-cmd program in package.json:
{
"scripts": {
"deploy": "env-cmd sls deploy"
}
}
Maintain and load all your environment specific configuration in project itself.
dev.js
module.exports = {
"host":"dev.com"
}
prod.js
module.exports = {
"host":"prod.com"
}
config.js - main file that will resolve configuration based on process.env.ENV variable.
const dev = require('./dev');
const prod = require('./prod');
let envObject = {};
const env = process.env.ENV || "dev";
switch(env) {
case 'prod':
envObject = prod;
break;
default:
envObject = dev;
}
envObject['ENV'] = env;
process.env = Object.assign(process.env,envObject); // Optional if you prefer to add them into process environment otherwise `require('./config')` where you need configuration.
module.exports = envObject;
index.js - node project root file call every time when project start
const config = require('./config');
console.log('config object => ',config.host);
package.json
{
"name": "project",
"version": "0.0.2",
"scripts": {
"deploy": "sls deploy"
}
}
Running you node.js code
Prod environment ENV=prod npm run deploy;
Development environment - npm run deploy;
Default environment is set to dev in ./config.js
Using this simple practice you don't need any npm module to manage your environment configurations.
I was having the same issue while trying to syncing the DB using an external command and fixed the issue by requiring dotenv package which will load the variables
"scripts": {
"db-sync": "node --require dotenv/config ./src/sequelize/sync.js"}
then just call npm run db-sync

Webpack/Express - environment variables not found by server

In my Express/React app, I am using Webpack to handle server-side rendering. However, I am experiencing a build error related to environment variables that I'm trying to access in my Express server script.
In the server script, index.js, I am setting a few variables like so:
const gitCommit = process.env.GIT_COMMIT || require("./gitignore/git_commit.js"),
buildDate = process.env.BUILD_DATE || require("./gitignore/build_date.js")
And since I am running a test production build on my local machine, I delete the gitignore/ directory and set those environment variables:
$ export GIT_COMMIT="test commit hash"
$ export BUILD_DATE="test build date"
Then I npm run build, which executes the following scripts:
"build:client": "webpack --config webpack.config.js",
"build:server": "webpack --config webpack.server.config.js",
"build": "npm run build:client && npm run build:server"
build:client executes with no problem, but build:server throws errors...
ERROR in ./index.js
Module not found: Error: Can't resolve './gitignore/git_commit.js' in '/Users/filepath'
# ./index.js 12:38-74
ERROR in ./index.js
Module not found: Error: Can't resolve './gitignore/build_date.js' in '/Users/filepath'
# ./index.js 13:42-78
implying that the two environment variables referenced in index.js can't be found, and so it's looking for the gitignore/ instead, which shouldn't exist (I mean, it does exist locally, but I've deleted since I'm simulating a production build).
Here is the complete webpack.server.config.js:
const fs = require("fs"),
path = require("path")// ,
// ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
"entry": path.resolve(__dirname, "index.js"),
// keep node_module paths out of the bundle
"externals": fs.readdirSync(path.resolve(__dirname, "node_modules")).concat(["react-dom/server", "react/addons"]).reduce((ext, mod) => {
ext[mod] = `commonjs ${mod}`
return ext
}, {}),
"module": {
"loaders": [
{
"exclude": /node_modules/,
"loader": "babel-loader",
"query": { "presets": ["react", "es2015", "stage-2"] },
"test": /\.jsx$/
},
{
"exclude": /node_modules/,
"loader": "babel-loader",
"query": { "presets": ["react", "es2015", "stage-2"] },
"test": /\.js$/
}
]
},
"node": {
"__dirname": true,
"__filename": true
},
"output": {
"filename": "server.bundle.js"
},
"target": "node"
}
Now I expect that gitignore/ would not be found, but what I don't understand is why the two environment variables that I set are not being detected by index.js - they are definitely set in the console before I even run the build command. If I console.log() them in the beginning of webpack.server.config.js, it logs them correctly, and if I run my development version instead (which doesn't use the server config), I can log them correctly in index.js. What gives?
Node version 6.11.1, NPM version 3.10.10, Webpack version 2.6.0.
Your environment variables are only available when Webpack runs, but not when you execute your index.js.
You will need to use the EnvironmentPlugin in your Webpack config like that:
plugins: [new webpack.EnvironmentPlugin(['GIT_COMMIT ', 'BUILD_DATE'])]
That plugin will replace the variables by their actual values.
HINT: Do not use ||. Webpack does not know how to optimize it. Try the ternary operator:
const gitCommit = (process.env.GIT_COMMIT) ? (
process.env.GIT_COMMIT
) : (
require('./gitignore/git_commit.js')
);
Webpack will bundle this to:
const gitCommit = (true) ? (
"test commit hash"
) : (
require('./gitignore/git_commit.js')
);
No IgnorePlugin is needed. Even better, with the UglifyJSPlugin, your code will be optimized to const gitCommit = "test commit hash";. In some cases gitCommit is removed completely as a variable. Its string value will be used instead anywhere where you applied gitCommit.

running jest through config gives error

I am trying to run jest by specifying a configuration file. The command line I am using is
"test": "jest -—config jest/jest.config.js",
My jest.config.js file looks like the following
module.exports = {
bail: true,
verbose: true,
moduleNameMapper: {
'\\.(css|jpg|png)$': '<rootDir>/empty-module.js-'
}
};
However when I run the npm command I keep getting the following error
validateCLIOptions.js:62
throw createCLIValidationError(unrecognizedOptions, allowedOptions);
^
←[31m←[1m←[1m●←[1m Unrecognized CLI Parameters←[22m:
You need another -- otherwise the parameter would send to npm not to jest
"jest -- --config jest/jest.config.js",

Failed to pass command-line arg into Webpack

I'm trying to pass arguments to Webpack via command like (I got the info from here):
// webpack.dev.conf.js
module.exports = function (env) {
if (env.compress === 'true') {
console.log('COMPRESS')
}
}
I did npm run dev --env.compress in the terminal. As you can see I'm have custom scripts:
"scripts": {
"dev": "node --max_old_space_size=10000 build/dev-server.js",
However, I get this error:
throw new Error("Invalid argument: options");
^
Error: Invalid argument: options
How to properly pass command-line arguments to Webpack?

Resources