-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use config to define absolute paths #3262
Comments
I found cypress-webpack-preprocessor can fullfill it In plugin file: const webpack = require('@cypress/webpack-preprocessor')
module.exports = (on) => {
const options = {
// send in the options from your webpack.config.js, so it works the same
// as your app's code
webpackOptions: require('../../webpack.config'),
watchOptions: {},
}
on('file:preprocessor', webpack(options))
} in webpack.config.js: var path = require('path')
module.exports = {
resolve: {
alias: {
Api: path.resolve(__dirname, 'cypress/support/api'),
Helper: path.resolve(__dirname, 'cypress/support/helper'),
Obj: path.resolve(__dirname, 'cypress/support/obj'),
Fixtures: path.resolve(__dirname, 'cypress/fixtures'),
Plugins: path.resolve(__dirname, 'cypress/plugins')
}
}
} Now, instead of using relative paths when importing like so: import Utility from '../../api/utility'; I can use the alias: import Utility from 'Api/utility'; |
Did you experience Cypress freezing up at all when running a spec file with an absolute import? If so, how did you get around this? |
@ennisbenjamind No, everything looks good in this solution. |
you have any other plugins set up by chance? |
Alternatively, to reference files relative to
Do:
const path = require('path');
const webpack = require('@cypress/webpack-preprocessor');
class CypressFileKindPlugin {
constructor(source, target) {
this.source = source;
this.target = target;
}
apply(resolver) {
resolver.plugin(this.source, (request, callback) => {
if (request.request.startsWith('~/')) {
const newPath = path.join(__dirname, '..', request.request.substr(2));
const newRelativePath = path.join(
request.relativePath,
path.relative(request.path, newPath));
const obj = Object.assign({}, request, {
path: newPath,
relativePath: newRelativePath,
request: undefined,
});
resolver.doResolve(this.target, obj, null, callback);
} else
return callback();
});
}
}
module.exports = (on, config) => {
on('file:preprocessor', webpack({
webpackOptions: {
resolve: {
plugins: [
new CypressFileKindPlugin('described-resolve', 'raw-file'),
],
}
},
}));
} If you want to add module.exports = (on, config) => {
const webpackOptions = Object.assign({}, webpack.defaultOptions.webpackOptions, {
module: {
rules: [{
test: /\.js$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader',
options: {
// babelrc: false, // in case you have .babelrc
// having .babelrc and passing options inline will result
// in a merge, potentially running plugins more than once
presets: ['env'],
plugins: ['transform-object-rest-spread'],
},
}],
}],
},
...
});
on('file:preprocessor', webpack({webpackOptions}));
} |
For those of you using Create React App with module.exports = on => {
// find the Webpack config used by react-scripts
const webpackOptions = findWebpack.getWebpackOptions();
if (!webpackOptions) {
throw new Error('Could not find Webpack in this project 😢');
}
const cleanOptions = {
reactScripts: true
};
findWebpack.cleanForCypress(cleanOptions, webpackOptions);
const options = {
webpackOptions,
watchOptions: {}
};
// Define your alias(es) here:
options.webpackOptions.resolve.alias.cypress = path.resolve(process.cwd(), 'cypress');
on('file:preprocessor', webpackPreprocessor(options));
} |
Cypress now uses ts-node instead of webpack, so I tried another method at solving this.
VersionCypress 5.0 Setup
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
// Add your paths here
}
}
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": "..",
}
}
// Make sure this is first
import "./register-tsconfig-paths"
export default function (on, config) {
return config
}
import tsConfig from "../../tsconfig.json"; // Your top-level config!
import * as tsConfigPaths from "tsconfig-paths";
const baseUrl = "./";
tsConfigPaths.register({
baseUrl,
paths: tsConfig.compilerOptions.paths
}); I just started using this workaround so I'm not sure if its bullet-proof, hopefully this saves someone an afternoon of head scratching. EDIT: Two months later, we haven't had any issues. For our solution we need to pass custom options to |
@marklawlor oh hallelujah!! Finally found your comment after trying several outdated blog post. This was all I needed to make it work: require("tsconfig-paths").register() |
|
I would recommend against using this solution. Using a nonstandard |
just a follow up on @BradRyan great pointer that led me to a working solution with Create React App (CRA) which uses this is how my /// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
const path = require('path')
const findWebpack = require('find-webpack')
const webpackPreprocessor = require('@cypress/webpack-preprocessor')
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
// USE ABSOLUTE PATHS
// find the Webpack config used by react-scripts - https://github.com/cypress-io/cypress/issues/3262#issuecomment-635550879
const webpackOptions = findWebpack.getWebpackOptions()
if (!webpackOptions) {
throw new Error('Could not find Webpack in this project 😢')
}
const cleanOptions = {
reactScripts: true,
}
findWebpack.cleanForCypress(cleanOptions, webpackOptions)
const options = {
webpackOptions,
watchOptions: {},
}
// Define your alias(es) here:
options.webpackOptions.resolve.alias['@fixtures'] = path.resolve(
process.cwd(),
'cypress',
'fixtures'
)
on('file:preprocessor', webpackPreprocessor(options))
} |
@flybayer can you hint where we add this? require("tsconfig-paths").register() |
@marklawlor, apologies for the TS/JS noob question, but appreciate any hints on what syntax looks like here:
|
|
Add it as the first line of |
@flybayer @marklawlor thanks for your effors! I keep getting the usual error
|
Current behavior:
I want to use absolute paths for module imports. Thus I set
cypress/tsconfig.json
like belowAnd in my test code, the profile_api is in
cypress/support/api/profile_api,
so the first import line:But always got the error:
Desired behavior:
Should be able to use absolute paths from
tsconfig.json
Versions
[email protected]
The text was updated successfully, but these errors were encountered: