Component
The principle of systems made of components and the quest for reusable components have driven lots of work in the OO software engineering since the early 80s. There is therefore a rather clear consensus about what it is.
The SWEBOK provides the following definition in section 7.Software Design Strategies and Methods:
A software component is an independent unit, having well-defined
interfaces and dependencies that can be composed and deployed
independently.
The UML specifications provide for similar semantic in section 11.6.3:
A Component is a self-contained unit that encapsulates the state and
behavior of a number of Classifiers. A Component specifies a formal
contract of the services that it provides to its clients and those
that it requires from other Components or services in the system in
terms of its provided and required Interfaces. A Component is a
substitutable unit that can be replaced at design time or run-time by
a Component that offers equivalent functionality based on
compatibility of its Interfaces.
The core idea of both definition is that the component is something that is self-contained ("independent ... having well-defined ... dependencies"), that provides an interface with a contract (i.e. a promised behavior, the latter being implied by "independently composable"), and is replaceable by another component offering the same interface and contract.
However, despite this consensus, component may still mean slightly different things to different people. For example, some consider that a component must be embodied in a deployable artefact (e.g. executable, dynamic library, ...), while other see the component already in the construction process (e.g. separate compilation unit).
Package
There is unfortunately lot less consensus on what a package is. The reason is that different mainstream technologies use the same term for different purpose. For example:
- A java package is a mean to group related classes and interfaces, by organizing a common namespace. In practice, packages often end up (alone or with other packages) in JARs which are deployable artifacts that could match the definition of a component.
- A Software deployment package is a group of files and configuration items that make a deployable software unit. Packages are in general versioned. Package managers allow to automate the deployment of such packages.
- An UML package is a way to structure complex models into smaller, more manageable sub-models, by regrouping packageable elements.
So depending on the context, it is a group of deployagble artifacts that form a whole (which is in fact very close to the definition of a component), a group of components, or just a subdivision of something larger. The only general consensus here seems to be that a package regroups artifacts.