Knowledge Base - Kinsta® https://kinsta.com/knowledgebase/ Fast, secure, premium hosting solutions Wed, 07 Aug 2024 12:38:01 +0000 en-US hourly 1 https://wordpress.org/?v=6.1.7 https://kinsta.com/wp-content/uploads/2024/09/cropped-Kinsta-black-favicon-1-32x32.png Knowledge Base - Kinsta® https://kinsta.com/knowledgebase/ 32 32 Deploy Laravel with Inertia.js on Kinsta’s Application Hosting platform https://kinsta.com/knowledgebase/laravel-inertia-app-hosting/ https://kinsta.com/knowledgebase/laravel-inertia-app-hosting/#respond Wed, 20 Mar 2024 15:06:37 +0000 https://kinsta.com/?p=175717&post_type=knowledgebase&preview_id=175717 Laravel, a powerful PHP framework, and Inertia.js, a dynamic JavaScript library, seamlessly collaborate to streamline app development. Laravel simplifies server-side tasks, while Inertia.js facilitates client-side interactions. Together, ...

The post Deploy Laravel with Inertia.js on Kinsta’s Application Hosting platform appeared first on Kinsta®.

]]>
Laravel, a powerful PHP framework, and Inertia.js, a dynamic JavaScript library, seamlessly collaborate to streamline app development. Laravel simplifies server-side tasks, while Inertia.js facilitates client-side interactions. Together, they support smooth data flow and real-time updates, helping you build responsive web applications quickly.

Deploying a Laravel-Inertia application using Kinsta’s Application Hosting service involves a few steps:

  1. Set up the database using Kinsta’s Database Hosting.
  2. Host your application and configure buildpacks for Node.js and PHP, integrating the database.
  3. Configure Node.js to install Inertia and PHP dependencies for the Inertia environment.

This tutorial walks you through this process step-by-step.

Understanding the deployment requirements

To follow along, ensure you have the following prerequisites:

In this article, you’ll deploy a blog application that serves a list of articles and lets the reader view a specific post. The application was styled using Tailwind CSS and built using Laravel and Vue.js.

The Node.js JavaScript runtime environment handles server-side rendering. It coordinates communication between the Inertia.js frontend application’s components and the Laravel backend for dynamic frontend updates from the server side.

Blog application with a list of articles and placeholder text
The Kinsta Blog application with a title and a list of articles.

For more information about how to build this application, read How to use Inertia.js in your Laravel projects. You can also download the app’s full source code.

How to deploy the application on Kinsta

Start by setting up a database for your application on Kinsta’s Database Hosting. This can be done by following these steps:

  1. Log in or create an account to view your MyKinsta dashboard.
  2. Click Databases on the left sidebar, then click Add database.
  3. In the Basic details section, enter your database’s details. This includes the Database type (MySQL) and Version (8.0). Then click Continue.
  4. The Summary section shows the service’s invoice details and your billing information. Confirm and click Create database.

How to configure the Laravel environment

To configure the Laravel environment on Kinsta’s Application Hosting. Follow these steps:

  1. Click Applications on the left sidebar of MyKinsta, then click Add application.
  2. Choose your application’s repository, enable automatic deployment on commit, enter the Application name, and select the Data center location. Your application and database must be in the same region.
  3. Next, enter your Environment variables. Type APP_KEY in the Key 1 field. Use the Laravel online generator to create a key for Value 1. Click Continue.
  4. On the Build environment tab, select Use Buildpacks to set up container image. This option lets you choose the buildpacks later.
  5. On the Resources tab, specify your application’s start command. Since this is a Laravel application, it uses the following command:
    php artisan serve --host 0.0.0.0 --port 8080
  6. The Summary tab shows the invoice with your pod and payment method. Confirm all information and click Create application.

Your application deployment starts. But it fails because you still need to add the buildpacks required during your Laravel-Inertia application’s build.

Add Buildpacks

  1. In the left-side menu of your application, click Settings.
  2. Next, click the build tab and Add buildpack to add the Node.js and PHP buildpacks. Add the buildpacks containing the primary language last to the buildpack list to ensure that the language-specific buildpack has precedence over the application environment’s general configuration.
  3. Click Add buildpack and add the Node.js and PHP buildpacks. Ensure that the primary language buildpack (PHP) is added last.

    Add buildpack screen, select Node.js and PHP
    Adding buildpacks for the Laravel-Inertia application.
  4. Click Deployment on the sidebar and click Redeploy.

Set up the Node.js environment

  1. The Laravel-Inertia application needs the Vite script for the page to update without reloading. So, in your Kinsta account’s left-side menu, click Processes.
  2. In the Runtime Processes section, click Create process. Choose Background worker as the process Type and add the following commands:
    npm install && npm start
    Create process for the application
    Creating Node.js start commands for the Laravel-Inertia application.

    Name the process whatever you want to identify it within Kinsta, like “Node”. Also, select the Pod Size and Instance count based on your application’s needs and budget. This tutorial uses 2 CPUs with 8GB of RAM.

  3. Click Continue to create your process. This action triggers a redeployment.

Set up the database environment

  1. On the Settings page, in the Connections tab, you should see Allowed applications. Click Add connection to add the database as a connection.
  2. Select the database. Below it, check Add environment variables to access the database. This action automatically populates all the database environment variables.
  3. Edit the variable keys to match your application’s database.php file, which is in the config folder at your application’s root.
  4. Modify the Laravel keys DB_DATABASE, DB_USERNAME, and DATABASE_URL, like in the following screenshot:

    A list of six keys and their redacted values
    Adding environment variables and modifying the keys.
  5. Add another environment variable called APP_URL. Its value is your application deployment URL. Get this information from Domains in the side menu.

Migrating the database

  1. In the side menu, click Processes.
  2. In the Runtime processes section, click Create process.
  3. Name the process “Migration”. Select the type Background worker. Paste the following command in the Start command field:
    php artisan migrate:fresh --seed --force

    This command migrates the Article table and adds ten articles to the application. Your processes should look like the following screenshot, with Node, Migration, and Web process and their details.

    A list of runtime processes including the process, type, instances, pod size, and edit or delete actions for Node, Migration, and Web process
    Runtime processes when deploying the Laravel-Inertia application.
  4. In the side menu, select Deployments. Click Latest deployment. You should see a page like the following, with a title and a list of articles with placeholder text and images.

    The application's home page with the title Kinsta Blog and a list of articles with placeholder text
    The Laravel-Inertia application is successfully deployed to Kinsta.

How to monitor and maintain the application post-deployment

After deploying your application, you may experience issues as its requests surge. Kinsta’s application analytics helps you monitor these changes and maintain your application’s health.

Analytics shows resources, performance, and HTTP requests to give you an idea of how your application operates. You can quickly observe when your application needs more resources in your performance tab’s monitor boards, then scale up or down as needed.

The runtime logs also help your team swiftly debug issues. You can find the source of the problem in the log entries, making it straightforward to maintain your application.

How to troubleshoot common deployment issues

You might encounter a couple of issues when deploying your Laravel-Inertia application to Kinsta. Let’s discuss what these issues are — and how to troubleshoot them.

First, Kinsta adds a special character to the generated password when you create a database. It can cause rollback errors when you connect the database to your Laravel-Inertia application. To troubleshoot this issue, use your password instead of relying on the generated passwords.

Auto-commit deployment failures are another typical issue. The deployment might fail if you specify the incorrect start command. To fix this issue, check if your processes have typos or are incorrectly assigned to a process type.

Summary

You now know how to deploy a Laravel and Inertia application to Kinsta. It involves setting Buildpacks and start commands to configure the application, creating a database, and then connecting and migrating the database to serve data to the application.

Combining Laravel and Inertial lets you connect your app and database without manually setting up an API, saving time and energy that you can use instead to create exciting new app features.

Kinsta hosts your application and its database. You can also use your database’s external connections to connect to an application running outside of Kinsta. 37 data centers help you offer services closer to your application’s users, reducing lag while offering a reliable, secure deployment infrastructure.

Use what you’ve learned in this tutorial to deploy your dynamic web application — or your database — to Kinsta. Start your deployment journey with Kinsta today.

The post Deploy Laravel with Inertia.js on Kinsta’s Application Hosting platform appeared first on Kinsta®.

]]>
https://kinsta.com/knowledgebase/laravel-inertia-app-hosting/feed/ 0
Mastering indexing in MySQL and MariaDB: A path to optimization https://kinsta.com/knowledgebase/indexing-in-mysql-mariadb/ https://kinsta.com/knowledgebase/indexing-in-mysql-mariadb/#respond Fri, 23 Feb 2024 16:20:50 +0000 https://kinsta.com/?post_type=knowledgebase&p=174861 Both MySQL and MariaDB seamlessly leverage the efficiency of balanced tree (B-Tree) indexing to optimize data operations. This shared indexing mechanism ensures swift data retrieval, enhances ...

The post Mastering indexing in MySQL and MariaDB: A path to optimization appeared first on Kinsta®.

]]>
Both MySQL and MariaDB seamlessly leverage the efficiency of balanced tree (B-Tree) indexing to optimize data operations. This shared indexing mechanism ensures swift data retrieval, enhances query performance, and minimizes disk input/output (I/O), contributing to a more responsive and efficient database experience.

This article takes a closer look at indexing, guides you on creating indexes, and shares tips on using them more effectively in MySQL and MariaDB databases.

What is an index?

When you query a MySQL database for specific information, the query searches through each row in a database table until it locates the correct one. This may take a long time, particularly in cases where the database is extensive.

Database managers use indexing to expedite data retrieval processes and optimize query efficiency. Indexing builds a data structure that minimizes the quantity of data that must be searched by organizing it systematically, leading to quicker and more effective query execution.

Say you want to find a customer whose first name is Ava in the following Customer table:

A MySQL Workbench preview of the Customer table showing the customer ID, first name, last name, and email address
MySQL Workbench preview of the Customer table.

Adding a B-Tree index to the first_name column creates a structure that facilitates a more efficient search for the desired information. The structure resembles a tree with the root node at the top, branching down to leaf nodes at the bottom.

It’s similar to a well-organized tree, where each level guides the search based on the sorted order of the data.

This image shows a B-Tree index search path:

A diagram of a B-Tree index search path for the Customers table
A B-Tree Customer table.

Ava is listed first, and William last in ascending alphabetical order — how the B-Tree arranged the names. The B-Tree system designates the middle value in the list as a root node. Since Michael is in the middle of the alphabetical list, it’s the root node. The tree then branches out, with values to Michael‘s left and right.

As you proceed down the tree’s tiers, each node offers more keys (direct links to the original rows of data) to guide the search through the alphabetically ordered names. Then, you find the data for every customer’s first name at the leaf nodes.

The search starts by comparing Ava to the root node Michael. It moves to the left after determining that Ava appears before Michael alphabetically. It travels down to the left child (Emily), then left again to Daniel, and left once more to Ava before arriving at the leaf node that contains Ava’s information.

The B-Tree functions as a simplified navigation system, effectively guiding the search to a particular place without checking every name in the dataset. It’s like navigating a carefully ordered directory by following strategically placed signposts that take you straight to the destination.

Types of indexes

There are different types of indexes for various purposes. Let’s discuss these different types below.

1. Single-level indexes

Single-level indexes, or flat indexes, map index keys to table data. Every key in the index corresponds to a single table row.

The customer_id column is a primary key in the Customer table, serving as a single-level index. The key identifies each customer and links their information in the table.

Index (customer_id) Row Pointer
1 Row 1
2 Row 2
3 Row 3
4 Row 4

The relationship between customer_id keys and individual customer details is straightforward. Single-level indexes excel in scenarios with tables containing a few rows or columns with few distinct values. Columns like status or category, for example, are good candidates.

Use a single-level index for simple queries that locate a specific row based on a single column. Its implementation is simple, straightforward, and efficient for smaller datasets.

2. Multi-level indexes

Unlike single-level indexes for organized data retrieval, multi-level indexes use a hierarchical structure. They have multiple levels of guidance. The top-level index directs the search to a lower-level index, and so on until it reaches the leaf level, which stores the data. This structure decreases the number of comparisons required during searches.

Consider a multi-level index with address and customer_id columns.

Index (address) Sub-Index (customer_id) Row Pointer
123 Main St 1 Row 1
456 Oak Ave 2 Row 2
789 Pine Rd 3 Row 3

The first level organizes addresses. The second level, within each address, further organizes customer IDs.

This organization is excellent for more extensive datasets that require an organized search hierarchy. It’s also helpful for columns like last_name with a moderate cardinality (the uniqueness of data values in a particular column).

3. Clustered indexes

Clustered indexes in MySQL dictate the index’s logical order and the data’s order in the table. If you apply a clustered index to the customer_id column in the Customer table, the rows are sorted based on the column’s values. This means that the order of the data in the table reflects the order of the clustered index, enhancing data retrieval performance for specific patterns by reducing disk I/O.

This strategy is effective when the data retrieval pattern aligns with the order of customer IDs. It’s also suitable for columns with high cardinality, like customer_id.

While clustered indexes offer advantages regarding data retrieval performance for specific patterns, it’s important to note a potential drawback. Sorting rows based on the clustered index can impact the performance of insert and update operations, especially if the insert or update pattern doesn’t align with the order of the clustered index. This is because new data must be inserted or updated in a way that maintains the sorted order, resulting in additional overhead.

4. Non-clustered indexes

Non-clustered indexes give database structures more flexibility. Assume you use a non-clustered index on an email column. Unlike a clustered index, it doesn’t change the order of the entries in the table.

Instead, it builds a new structure that maps keys — in this case, email addresses — to data rows. When you query the database for a specific email address, the non-clustered index guides the search directly to the relevant row without relying on the table’s order.

The flexibility of non-clustered indexes is their primary advantage. They enable efficient searches of multiple columns without imposing an order on the stored data. This system makes non-clustered indexes versatile, as they can accommodate queries that don’t follow the primary order of the table.

Non-clustered indexes are helpful when the data retrieval pattern differs from alphabetical order and for columns with moderate to high cardinality, like email.

How to create indexes

Now that we’ve reviewed what indexes are from a high level let’s review some practical examples of creating indexes using MySQL Workbench.

Prerequisites

To follow along, you need:

  • A MySQL database (compatible with MariaDB)
  • Some SQL and MySQL experience
  • MySQL Workbench

How to create the customer table

  1. Launch MySQL Workbench and connect to your MySQL server.
  2. Run the following SQL query to create a Customer table:
    CREATE TABLE Customer (
        customer_id INT PRIMARY KEY,
        first_name VARCHAR(50),
        last_name VARCHAR(50),
        email VARCHAR(100),
        phone_number VARCHAR(15),
        address VARCHAR(255)
    );
  3. Insert the following data:
    -- Adding Data to the Customer Table
    INSERT INTO Customer (customer_id, first_name, last_name, email, phone_number, address)
    VALUES
        (1, 'John', 'Doe', 'john.doe@email.com', '123-456-7890', '123 Main St'),
        (2, 'Jane', 'Smith', 'jane.smith@email.com', '987-654-3210', '456 Oak Ave'),
        (3, 'Robert', 'Johnson', 'robert.johnson@email.com', '111-222-3333', '789 Pine Rd'),
        (4, 'Emily', 'Williams', 'emily.williams@email.com', '555-666-7777', '101 Cedar Ln'),
        (5, 'Michael', 'Brown', 'michael.brown@email.com', '444-555-8888', '202 Elm St'),
        (6, 'Sophia', 'Davis', 'sophia.davis@email.com', '999-888-7777', '303 Maple Ave'),
        (7, 'Daniel', 'Miller', 'daniel.miller@email.com', '777-888-9999', '404 Birch Rd'),
        (8, 'Olivia', 'Jones', 'olivia.jones@email.com', '333-222-1111', '505 Pine St'),
        (9, 'William', 'Wilson', 'william.wilson@email.com', '111-333-5555', '606 Oak Ln'),
        (10, 'Ava', 'Moore', 'ava.moore@email.com', '888-777-6666', '707 Cedar Ave');

Single-level indexes

One tactic for optimizing query performance in MySQL and MariaDB is to use single-level indexes.

To add a single-level index to the Customer table, use the CREATE INDEX statement:

-- Creating a Single-Level Index on "customer_id"
CREATE INDEX idx_customer_id ON Customer(customer_id);

Upon successful execution, the database confirms index creation by returning the following code:

0 row(s) affected Records: 0  Duplicates: 0 Warnings: 0

Now, queries that filter data based on values from the customer_id column are handled optimally by the database, greatly increasing efficiency.

Multi-level indexes

MySQL and MariaDB go beyond individual column indexing by providing multi-level indexes. These indexes span more than one level or column, combining values from multiple columns into one index to make executing queries more efficient.

Use the following code to create a multi-level index in MySQL or MariaDB, focusing on address and customer_id columns:

-- Creating a Multi-Level Index based on "address" and "customer_id"
CREATE INDEX idx_address_customer_id ON Customer(address, customer_id);

Using multi-level indexes strategically results in significant improvements in query performance, especially when dealing with sets of columns.

Clustered indexes

Besides individual and multi-level indexing, MySQL and MariaDB use clustered indexes, a dynamic tool for enhancing database performance by aligning the data rows with the order of the index’s pointers.

For instance, applying a clustered index to the customer_id column in the Customer table aligns the order of customer IDs.

-- Creating a Clustered Index on "customer_id"
CREATE CLUSTERED INDEX idx_customer_id_clustered ON Customer(customer_id);

Because of the optimized order of data, this strategy significantly improves the data retrieval of specific patterns while decreasing disk I/O.

Non-clustered indexes

Non-clustered indexes can optimize queries depending on the columns without forcing the data into a certain order. In MySQL and MariaDB, you don’t need to specify that an index is non-clustered.

The table architecture implies it. Only the primary key or the first non-null unique key can be a clustered index. The table’s other indexes are all implicitly non-clustered. As an example of a non-clustered index, consider the following:

-- Creating a Non-clustered Index on "email"
CREATE INDEX idx_email_non_clustered ON Customer(email);

Non-clustered indexes allow for efficient searches of multiple columns, resulting in a more versatile and responsive database.

Best practices and key points

Choose single-level indexes when working with columns with a small range of differing values, like status or category. Use multi-level and non-clustered indexes with columns with a broader range of values, like email.

Your preferred data retrieval patterns are key when choosing between clustered and non-clustered indexes. For clustered indexes, choose columns with high cardinality, like customer ID. For non-clustered indexes, choose columns with moderate to high cardinality, like email.

How to optimize indexes

To boost the performance of your indexes, you can use some practical strategies, such as covering indexes and removing redundant indexes.

1. Cover indexes

Covering indexes improves query performance by creating indexes that cover all necessary data. The term covering index means an index includes all the columns required to fulfill a query, avoiding the need to access the data rows.

-- Create a Covering Index on "first_name" and "last_name"
CREATE INDEX idx_covering_name ON Customer(first_name, last_name);

2. Remove redundancies

Remove redundant indexes, but exercise caution, as removing indexes may impact certain query performances.

-- Remove an Unnecessary Index
DROP INDEX idx_unnecessary_index ON Customer;

Regularly review and remove redundant indices to ensure a streamlined and efficient database structure.

3. Avoid over-indexing

Avoid common pitfalls like over-indexing. While indexes enhance query performance, creating too many can diminish returns. It’s crucial to strike a balance and avoid over-indexing, which may result in increased storage requirements and potential performance degradation.

4. Analyze query patterns

It’s also a common pitfall to overlook the analysis of query patterns before creating indexes. Understanding the queries frequently executed and focusing on indexing columns used in WHERE clauses or JOIN conditions is essential for optimal performance.

Summary

This article explored MySQL and MariaDB indexing, emphasizing the efficiency of the B-Tree mechanism. It covered indexing fundamentals and various index types (single-level, multi-level, clustered, and non-clustered).

Whether you’re optimizing for read-heavy workloads or enhancing write performance, Kinsta’s database hosting service empowers MySQL and MariaDB users with a reliable and high-performance solution for their indexing needs. Try Kinsta’s database hosting to take advantage of MySQL and MariaDB and their indexing capabilities.

The post Mastering indexing in MySQL and MariaDB: A path to optimization appeared first on Kinsta®.

]]>
https://kinsta.com/knowledgebase/indexing-in-mysql-mariadb/feed/ 0
Solved: “Cannot Use Import Statement Outside a Module” Error https://kinsta.com/knowledgebase/cannot-use-import-statement-outside-module/ https://kinsta.com/knowledgebase/cannot-use-import-statement-outside-module/#comments Mon, 13 Nov 2023 16:28:01 +0000 https://kinsta.com/?post_type=knowledgebase&p=168133 The error message “Cannot use import statement outside a module” occurs when the import keyword is encountered in an improperly configured JavaScript or TypeScript module. In ...

The post Solved: “Cannot Use Import Statement Outside a Module” Error appeared first on Kinsta®.

]]>
The error message “Cannot use import statement outside a module” occurs when the import keyword is encountered in an improperly configured JavaScript or TypeScript module.

In a JavaScript server-side runtime environment, this error usually results from the use of import syntax for modules written in ECMAScript (ES) when Node.js is expecting the require keyword used by CommonJS module system.

TypeScript supports different module formats, but coding errors that confuse the ES and CommonJS approaches to importing modules also result in this error.

On the browser side, the error typically occurs when you don’t use a bundler for your JavaScript code files.

This article explores these three error sources and details a solution for each environment.

How to resolve the error in server-side JavaScript

This section demonstrates how to solve the error in server-side JavaScript environments.

Background

Node.js uses the CommonJS system’s require keyword by default. Therefore, you’ll receive the familiar error unless you configure Node.js to support ES module syntax. Similarly, Node.js requires the .mjs extension to recognize and work with ES modules.

Solution

As an alternative to using .mjs, you can make older versions of Node.js compatible with the current ES module by using bundlers or running Node.js with the --experimental-modules flag. Otherwise, you could set the type field in the package.json file to module as follows:

{
  "name": "test-package",
  "version": "1.0.0",
  "type": "module",
  "main": "app.js",
  "dependencies": { }
}

(Note: You should include the type property in the package.json file in all packages. This practice makes it easier to identify the module system in use and ensure consistency among your libraries.)

Another way to avoid the error is to ensure that the import and export syntaxes are correct and load properly. It’s critical to always use relative file paths, named exports, file extensions for exports, and avoid default exports.

Here’s an example:

//module import 
import { sampleFunction } from './sampleModule.js';

// function export
export function sampleFunction() {
     // code goes here
}

Finally, you should ensure the compatibility of all third-party libraries with ES modules. For this information, refer to the library documentation for the package.json file. Alternatively, use a bundler to transpile the code so a JavaScript environment can understand it.

How to resolve the error in TypeScript environments

This section demonstrates how to solve the error message in TypeScript environments.

Background

With modules, you can reuse, organize, and share code among multiple files in a project. ES supports external modules for sharing code among various files using the import and export keywords.

This error usually occurs in TypeScript environments when using the ES module syntax without configuring TypeScript to use it. Since TypeScript is a superset of JavaScript, it defaults to using CommonJS syntax for imports, which uses require instead of import. In this case, the import statement causes the error. Nevertheless, correctly configuring TypeScript is necessary for it to support ES modules.

You might also encounter this error if you use the incorrect file extension. For instance, when using TypeScript in a Node.js environment with ES module syntax, the module you want to import must have the .mjs file extension instead of the regular .js.

Another common source of the error is the improper configuration of the module field in your tsconfig.json or package.json files when using bundlers like Webpack. H

owever, you can use bundlers for ES modules in TypeScript by setting the module and target fields in the tsconfig.json file to ECMAScript. Then, Webpack will understand the target environment and use the correct file extensions when transpiling the code.

Solution

To load ES modules using a module loader like RequireJS or a bundler like Webpack, make the following additions to the tsconfig.json file:

{
  "compilerOptions": {
    "module": "es20215",
    "target": "es20215",
    "sourceMap": true
  }
}

In the compilerOptions portion of the code above, the module and target fields are set to use an es20215 module. With these additions, you can use the import and export statements in a TypeScript environment without causing the error.

As TypeScript uses CommonJS by default, failing to modify the tsconfig.json file accordingly will result in the error message.

Fortunately, once you’ve set the module and target fields to use an ECMAScript module, you can use the export statement to export a function or variable from a module and the import statement to load another module into the current one’s scope. This process occurs in the code below:

// sum.ts
export function sum(a: number, b: number, c: number): number {
  return a + b + c;
}

// main.ts
import { sum } from './sum';
console.log(add(4, 4, 9));

If you’re using an older version of Node.js, you can enable ES module support by running your code with the --experimental-modules flag. You should also use a bundler like Webpack, Browserify, or Rollup to bundle all the ES code and output it to a single file. Ensure that it’s in a version that browsers and old Node.js versions can understand and set up a Webpack.config.js file in the root of your project that specifies the module type.

Here’s an example extracted from the Webpack documentation:

module.exports = {
  entry: './src/index.ts',
  output: {
    filename: 'bundle.js',
   path: path.resolve(__dirname, 'dist')
  },
  resolve: {
    extensions: ['.ts', '.js', '.mjs']
  },
  module: {
    rules: [
      {
        test: /.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  experiments: {
    outputModule: true
  }
};

The compiled code is output to a bundle.js file in the dist directory of the project’s root directory.

You can also use polyfills like es-module-shims to target older browsers that don’t support ES modules’ import and export statements.

How to resolve the error in browser-side JavaScript

This section shows you how to solve the error in browser-side JavaScript environments.

Background

Most modern browsers, including Chrome, Firefox, Edge, and Safari, support ES modules, so you won’t need to use browser polyfills, bundlers, or transpilers.

You also don’t need them if you use the React or Vue JavaScript-based frontend libraries because they support the ES imports and exports fields by default. However, older browsers don’t support ES syntax, so they require these tools for cross-platform compatibility.

The most prevalent reason for the error in an older browser is when a page’s HTML files do not contain the type="module" attribute. In this scenario, the error occurs because JavaScript running on the web doesn’t include default support for ES module syntax. For JavaScript code sent across the wire, you might encounter a cross-origin resource-sharing error when attempting to load an ES module from a different domain.

Solution

To prevent the module error in an older browser, ensure that you’re using the correct script tag attribute — type="module" — in the root HTML file. Alternatively, you can use Webpack to transpile the code so that older browsers can understand it.

To use the type="module" attribute, include the following line in your root HTML file:

<script type="module" src="app.js"></script>

It’s equally critical to ensure the import file paths are valid and that you’re using the correct import syntax.

Additionally, you can visit sites like Can I Use to confirm browser compatibility for ES modules.

Finally, since using the .js file extension is common practice, you can set the type attribute in the module’s HTML file script tag as a workaround. Setting this attribute to module tells the browser to disregard the .js extension and treat the file as a module.

Summary

The “Cannot use import statement outside a module” error may appear for various reasons, depending on whether you’re in a browser-side or server-side JavaScript environment. Incorrect syntax, improper configurations, and unsupported file extensions remain a few of the most common sources of this error.

While most modern browsers support ES modules, you must ensure that older browsers are compatible. Bundlers like Webpack allow you to compile all source code with their dependencies to a single output that older browsers can understand.

Remember to add the type="module" attribute in the HTML file to inform the browser that the module is an ES module. Finally, while using the .js extension for CommonJS is the default practice, you can use the .mjs extension to enable importing ES modules.

Do you have a JavaScript application you need to get online but don’t want to manage the servers yourself? Kinsta’s Application Hosting and Database Hosting platforms could be the answer. You might even combine those services with Kinsta’s Static Site Hosting to have the front end of your application served up for free.

The post Solved: “Cannot Use Import Statement Outside a Module” Error appeared first on Kinsta®.

]]>
https://kinsta.com/knowledgebase/cannot-use-import-statement-outside-module/feed/ 3